Repository: NethermindEth/juno
Pull request #75 (2022-02-11 14:40:09)

[Core] Implementing openrpc
## Changes:
- Add basic cli using [cobra](https://cobra.dev) for juno commads
- Add RPC client base
- Add RPC server first steps, based on [this](https://github.com/starkware-libs/starknet-specs/blob/master/api/starknet_api_openrpc.json)

This PR doesn't include implementations of methods, should return empty response for now

OpenRPC server endpoints added so far:
- [x] Echo (response exactly the same it receives)
- [x] `starknet_getBlockByHash` 
- [x] `starknet_getBlockByNumber` 
- [x] `starknet_getStateUpdateByHash` 
- [x] `starknet_getStorageAt` 
- [x] `starknet_getTransactionByHash` 
- [x] `starknet_getTransactionByBlockHashAndIndex` 
- [x] `starknet_getTransactionByBlockNumberAndIndex` 
- [x] `starknet_getTransactionReceipts` 
- [x] `starknet_getCode` 
- [x] `starknet_getBlockTransactionCountByHash` 
- [x] `starknet_getBlockTransactionCountByNumbert` 
- [x] `starknet_call` 
- [x] `starknet_blockNumber` 
- [x] `starknet_chainId` 
- [x] `starknet_pendingTransactions` 
- [x] `starknet_protocolVersion` 
- [x] `starknet_syncing` 
- [x] `starknet_getEvents` 

## Types of changes

What types of changes does your code introduce?
_Put an `x` in the boxes that apply_

- [ ] Bugfix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation Update
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no api changes)
- [x] Build related changes
- [ ] Other (please describe): 

## Testing
**Requires testing**

- [x] Yes
- [ ] No

**In case you checked yes, did you write tests??**

- [ ] Yes
- [ ] No
- [x] Not Yet

**Comments about testing , should you have some** (optional)

## Further comments (optional)
RPC calls should be tested 

codecov-commenter: # [Codecov](https://codecov.io/gh/NethermindEth/juno/pull/75?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth) Report
> Merging [#75](https://codecov.io/gh/NethermindEth/juno/pull/75?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth) (b042ca0) into [main](https://codecov.io/gh/NethermindEth/juno/commit/2879116cb1ceeba3091ab73fde572ce39ba2e042?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth) (2879116) will **decrease** coverage by `73.14%`.
> The diff coverage is `16.84%`.

[![Impacted file tree graph](https://codecov.io/gh/NethermindEth/juno/pull/75/graphs/tree.svg?width=650&height=150&src=pr&token=HwJpZ8kijD&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth)](https://codecov.io/gh/NethermindEth/juno/pull/75?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth)

```diff
@@             Coverage Diff              @@
##              main      #75       +/-   ##
============================================
- Coverage   100.00%   26.85%   -73.15%     
============================================
  Files            2        7        +5     
  Lines           13      108       +95     
============================================
+ Hits            13       29       +16     
- Misses           0       78       +78     
- Partials         0        1        +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `26.85% <16.84%> (-73.15%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/NethermindEth/juno/pull/75?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth) | Coverage Δ | |
|---|---|---|
| [pkg/rpc/call.go](https://codecov.io/gh/NethermindEth/juno/pull/75/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3JwYy9jYWxsLmdv) | `0.00% <0.00%> (ø)` | |
| [pkg/rpc/echo.go](https://codecov.io/gh/NethermindEth/juno/pull/75/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3JwYy9lY2hvLmdv) | `0.00% <0.00%> (ø)` | |
| [pkg/rpc/rpc.go](https://codecov.io/gh/NethermindEth/juno/pull/75/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3JwYy9ycGMuZ28=) | `0.00% <0.00%> (ø)` | |
| [pkg/rpc/service\_register.go](https://codecov.io/gh/NethermindEth/juno/pull/75/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3JwYy9zZXJ2aWNlX3JlZ2lzdGVyLmdv) | `0.00% <0.00%> (ø)` | |
| [pkg/starknet\_client.go](https://codecov.io/gh/NethermindEth/juno/pull/75/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3N0YXJrbmV0X2NsaWVudC5nbw==) | `53.33% <53.33%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/NethermindEth/juno/pull/75?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/NethermindEth/juno/pull/75?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth). Last update [2879116...b042ca0](https://codecov.io/gh/NethermindEth/juno/pull/75?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth).


Patch:
diff --git a/Makefile b/Makefile
index edc949c5..d4401a9e 100644
--- a/Makefile
+++ b/Makefile
@@ -35,5 +35,8 @@ gomod_tidy: ## add missing and remove unused modules
 gofmt: ## run go formatter
 	go fmt -x ./...
 
+clean: ## Clean project builds
+	@rm -rf ./build/juno
+
 help: ## Show this help
 	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
diff --git a/README.md b/README.md
index ad03b815..6332f226 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ Run the following command.
 
 ```yaml
 rpc:
-  enabled: true
+  enabled: false
   port: 8080
 db_path: $HOME/.juno/data
 ```
diff --git a/cmd/juno/cli/root.go b/cmd/juno/cli/root.go
index 75f63f8d..7b4a7ac6 100644
--- a/cmd/juno/cli/root.go
+++ b/cmd/juno/cli/root.go
@@ -1,31 +1,23 @@
 package cli
 
+// notest
 import (
 	_ "embed"
 	"fmt"
 	"os"
+	"os/signal"
 	"path/filepath"
+	"syscall"
 
+	"github.com/NethermindEth/juno/internal/config"
 	"github.com/NethermindEth/juno/internal/errpkg"
 	"github.com/NethermindEth/juno/internal/log"
-	"github.com/NethermindEth/juno/internal/ospkg"
+	"github.com/NethermindEth/juno/internal/process"
+	"github.com/NethermindEth/juno/pkg/rpc"
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
-	"gopkg.in/yaml.v2"
 )
 
-// rpcConfig represents the juno RPC configuration.
-type rpcConfig struct {
-	Enabled bool `yaml:"enabled" mapstructure:"enabled"`
-	Port    int  `yaml:"port" mapstructure:"port"`
-}
-
-// config represents the juno configuration.
-type config struct {
-	Rpc    rpcConfig `yaml:"rpc" mapstructure:"rpc"`
-	DbPath string    `yaml:"db_path" mapstructure:"db_path"`
-}
-
 // Cobra configuration.
 var (
 	// cfgFile is the path of the juno configuration file.
@@ -39,7 +31,35 @@ var (
 		Use:   "juno [options]",
 		Short: "Starknet client implementation in Go.",
 		Long:  longMsg,
-		Run:   func(cmd *cobra.Command, args []string) {},
+		Run: func(cmd *cobra.Command, args []string) {
+			fmt.Println(longMsg)
+
+			handler := process.NewHandler()
+
+			// Handle signal interrupts and exits.
+			sig := make(chan os.Signal)
+			signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
+			go func() {
+				<-sig
+				log.Default.Info("Trying to close...")
+				handler.Close()
+				log.Default.Info("App closing...Bye!!!")
+				os.Exit(0)
+			}()
+
+			// Subscribe the RPC client to the main loop if it is enabled in
+			// the config.
+			if config.Runtime.Rpc.Enabled {
+				s := rpc.NewServer(":8080")
+				handler.Add("RPC", s.ListenAndServe, s.Close)
+			}
+
+			// endless running process
+			log.Default.Info("Starting all processes...")
+			handler.Run()
+			handler.Close()
+			log.Default.Info("App closing...Bye!!!")
+		},
 	}
 )
 
@@ -49,17 +69,17 @@ func init() {
 	cobra.OnInitialize(initConfig)
 
 	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", fmt.Sprintf(
-		"config file (default is %s)",
-		filepath.Join(ospkg.ConfigDir, "juno", "juno.yaml")))
+		"config file (default is %s)", filepath.Join(config.Dir, "juno.yaml")))
 }
 
-// initConfig reads in config file or environment variables if set.
+// initConfig reads in Config file or environment variables if set.
 func initConfig() {
 	if cfgFile != "" {
-		// Use config file specified by the flag.
+		// Use Config file specified by the flag.
 		viper.SetConfigFile(cfgFile)
 	} else {
-		viper.AddConfigPath(filepath.Join(ospkg.ConfigDir, "juno"))
+		// Use the default path for user configuration.
+		viper.AddConfigPath(config.Dir)
 		viper.SetConfigType("yaml")
 		viper.SetConfigName("juno")
 	}
@@ -73,42 +93,19 @@ func initConfig() {
 		log.Default.With("File", viper.ConfigFileUsed()).Info("Using config file:")
 	} else {
 		log.Default.Info("Config file not found.")
-
-		// Create default config.
-		cfgPath := filepath.Join(ospkg.ConfigDir, "juno", "juno.yaml")
-		log.Default.With("Path", cfgPath).Info("Creating default config.")
-
-		// Create the juno configuration directory if it does not exist.
-		cfgDirPath := filepath.Join(ospkg.ConfigDir, "juno")
-		if _, err := os.Stat(cfgDirPath); os.IsNotExist(err) {
-			err := os.MkdirAll(cfgDirPath, 0755)
-			errpkg.CheckFatal(err, "Failed to create config directory.")
-		}
-
-		data, err := yaml.Marshal(&config{
-			Rpc:    rpcConfig{Enabled: true, Port: 8080},
-			DbPath: filepath.Join(ospkg.DataDir, "juno"),
-		})
-		errpkg.CheckFatal(err, "Failed to marshal Config instance to byte data.")
-		err = os.WriteFile(cfgPath, data, 0644)
-		errpkg.CheckFatal(err, "Failed to write config file.")
-
+		config.New()
 		err = viper.ReadInConfig()
-		errpkg.CheckFatal(err, "Failed to read in config after generation.")
+		errpkg.CheckFatal(err, "Failed to read in Config after generation.")
 	}
 
-	// Log configuration values.
-	var cfg *config
-	err = viper.Unmarshal(&cfg)
-	if err != nil {
-		log.Default.With("Error", err).Panic("Unable to unmarshal configuration.")
-		return
-	}
+	// Unmarshal and log runtime config instance.
+	err = viper.Unmarshal(&config.Runtime)
+	errpkg.CheckFatal(err, "Unable to unmarshal runtime config instance.")
 	log.Default.With(
-		"Database Path", cfg.DbPath,
-		"Rpc Port", cfg.Rpc.Port,
-		"Rpc Enabled", cfg.Rpc.Enabled,
-	).Info("Configuration values.")
+		"Database Path", config.Runtime.DbPath,
+		"Rpc Port", config.Runtime.Rpc.Port,
+		"Rpc Enabled", config.Runtime.Rpc.Enabled,
+	).Info("Config values.")
 }
 
 // Execute handle flags for Cobra execution.
diff --git a/go.mod b/go.mod
index 80e61d5c..2794b3f8 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,9 @@ module github.com/NethermindEth/juno
 go 1.17
 
 require (
-	github.com/sirupsen/logrus v1.8.1
+	github.com/ethereum/go-ethereum v1.10.16
+	github.com/goccy/go-json v0.9.5
+	github.com/iancoleman/strcase v0.2.0
 	github.com/spf13/cobra v1.3.0
 	github.com/spf13/viper v1.10.1
 	github.com/torquem-ch/mdbx-go v0.22.15
@@ -12,23 +14,30 @@ require (
 )
 
 require (
+	github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
+	github.com/deckarep/golang-set v1.8.0 // indirect
 	github.com/fsnotify/fsnotify v1.5.1 // indirect
+	github.com/go-ole/go-ole v1.2.1 // indirect
+	github.com/go-stack/stack v1.8.0 // indirect
+	github.com/gorilla/websocket v1.4.2 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/inconshreveable/mousetrap v1.0.0 // indirect
-	github.com/kr/text v0.2.0 // indirect
 	github.com/magiconair/properties v1.8.5 // indirect
 	github.com/mitchellh/mapstructure v1.4.3 // indirect
 	github.com/pelletier/go-toml v1.9.4 // indirect
-	github.com/pkg/errors v0.9.1 // indirect
+	github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
 	github.com/spf13/afero v1.6.0 // indirect
 	github.com/spf13/cast v1.4.1 // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/subosito/gotenv v1.2.0 // indirect
+	github.com/tklauser/go-sysconf v0.3.5 // indirect
+	github.com/tklauser/numcpus v0.2.2 // indirect
 	go.uber.org/atomic v1.7.0 // indirect
 	go.uber.org/multierr v1.6.0 // indirect
+	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
 	golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
 	golang.org/x/text v0.3.7 // indirect
-	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
 	gopkg.in/ini.v1 v1.66.2 // indirect
+	gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
 )
diff --git a/go.sum b/go.sum
index 0264e1ea..7ed8f76e 100644
--- a/go.sum
+++ b/go.sum
@@ -1,11 +1,13 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg=
 cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
 cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
 cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
 cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
 cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
 cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
 cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
 cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
@@ -33,6 +35,7 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf
 cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
 cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
 cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
@@ -45,29 +48,73 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
+github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
+github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4=
+github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
+github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
+github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
+github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
+github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
+github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
+github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
 github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
+github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
+github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw=
+github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
+github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/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-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=
 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.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo=
+github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y=
+github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8=
+github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4=
+github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0=
+github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM=
+github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw=
 github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
 github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c=
+github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
+github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
+github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
+github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
+github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
+github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
+github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
+github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
+github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -77,6 +124,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
 github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
 github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -87,13 +135,32 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH
 github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ=
+github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
 github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
 github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
+github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
+github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 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/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
+github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
+github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
+github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
+github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
+github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
+github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -105,12 +172,24 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
 github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
+github.com/ethereum/go-ethereum v1.10.16 h1:3oPrumn0bCW/idjcxMn5YYVCdK7VzJYIvwGZUGLEaoc=
+github.com/ethereum/go-ethereum v1.10.16/go.mod h1:Anj6cxczl+AHy63o4X9O8yWNHuN5wMpfb8MAnHkWn7Y=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
+github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
 github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
+github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
+github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
+github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
+github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
+github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -118,10 +197,23 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 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-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
+github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/goccy/go-json v0.9.5 h1:ooSMW526ZjK+EaL5elrSyN2EzIfi/3V0m4+HJEDYLik=
+github.com/goccy/go-json v0.9.5/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gofrs/uuid v3.3.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.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
+github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -153,9 +245,13 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
 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/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -169,6 +265,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
 github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -189,15 +286,22 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe
 github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 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/google/uuid v1.1.5/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.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
 github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
 github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
 github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
 github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
 github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
 github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
 github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
@@ -217,6 +321,7 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
 github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
@@ -226,20 +331,54 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn
 github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
 github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
 github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
+github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
+github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM=
+github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
+github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
 github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
+github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI=
+github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8=
+github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk=
+github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE=
+github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
+github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
+github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8=
+github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
+github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
+github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
+github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
+github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU=
+github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o=
+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/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
+github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
+github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
+github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
+github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
+github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/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/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
@@ -251,20 +390,39 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
+github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
+github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
 github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
 github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
+github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
 github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
 github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
@@ -274,23 +432,47 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
 github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
 github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
 github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
+github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
 github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
 github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
+github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
+github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
+github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@@ -302,39 +484,57 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
+github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
 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/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
 github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
+github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
+github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU=
+github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
+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.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
-github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
 github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
 github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
 github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0=
 github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
 github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
 github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
 github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
 github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
+github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
 github.com/stretchr/objx v0.1.0/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.0/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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -344,9 +544,22 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
 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/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
+github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
+github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4=
+github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
+github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA=
+github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
 github.com/torquem-ch/mdbx-go v0.22.15 h1:mFMP1lC0716ifEAvg8FoJ1iJCXww0UFe4aRgbfTRAYY=
 github.com/torquem-ch/mdbx-go v0.22.15/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E=
 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
+github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
+github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
+github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
+github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
+github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
 github.com/yuin/goldmark v1.1.25/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=
@@ -363,26 +576,38 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 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.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
 go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 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/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
 go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
 go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
+golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
 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-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/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-20190125153040-c74c464bbbf2/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-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
@@ -392,6 +617,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -420,6 +646,7 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
 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-20180906233101-161cd47e91fd/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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -444,20 +671,24 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
 golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/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-20201031054903-ff519b6c9102/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-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
 golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -490,7 +721,9 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
 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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -502,13 +735,18 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
 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-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -522,21 +760,28 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -555,6 +800,7 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
 golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -569,12 +815,18 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 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-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
@@ -592,6 +844,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@@ -627,6 +880,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
+gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
+gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
+gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
+gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
+gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -672,6 +931,7 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
 google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/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=
@@ -679,6 +939,7 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx
 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
@@ -779,19 +1040,27 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
 gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
+gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
+gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
 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.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.5/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/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 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-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
 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-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -799,6 +1068,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/internal/config/config.go b/internal/config/config.go
new file mode 100644
index 00000000..a6786247
--- /dev/null
+++ b/internal/config/config.go
@@ -0,0 +1,87 @@
+// Package config provides constants and functions related to the
+// application's configuration.
+package config
+
+import (
+	"errors"
+	"os"
+	"path/filepath"
+	"runtime"
+
+	"github.com/NethermindEth/juno/internal/errpkg"
+	"github.com/NethermindEth/juno/internal/log"
+	"gopkg.in/yaml.v2"
+)
+
+// rpcConfig represents the juno RPC configuration.
+type rpcConfig struct {
+	Enabled bool `yaml:"enabled" mapstructure:"enabled"`
+	Port    int  `yaml:"port" mapstructure:"port"`
+}
+
+// Config represents the juno configuration.
+type Config struct {
+	Rpc    rpcConfig `yaml:"rpc" mapstructure:"rpc"`
+	DbPath string    `yaml:"db_path" mapstructure:"db_path"`
+}
+
+var (
+	// Dir is the default root directory for user-specific
+	// configuration data.
+	//
+	// On Darwin this is $HOME/Library/Application Support/juno/, on other
+	// Unix systems $XDG_CONFIG_HOME/juno/, and on Windows,
+	// %APPDATA%/juno.
+	Dir,
+	// DataDir is the is the default root directory for user-specific
+	// application data.
+	//
+	// On Unix this is $XDG_DATA_HOME/juno/ and on Windows,
+	// %APPDATA%/juno/.
+	DataDir string
+)
+
+// Runtime is the runtime configuration of the application.
+var Runtime *Config
+
+func init() {
+	// Set user config directory.
+	d, err := os.UserConfigDir()
+	errpkg.CheckFatal(err, "Unable to get the user config directory.")
+	Dir = filepath.Join(d, "juno")
+
+	// Set user data directory.
+	DataDir, err = func() (string, error) {
+		// notest
+		switch runtime.GOOS {
+		case "windows":
+			// On Windows ConfigDir and DataDir share the same path. See:
+			// https://stackoverflow.com/questions/43853548/xdg-basedir-directories-for-windows
+			return Dir, nil
+		case "darwin", "dragonfly", "freebsd", "illumos", "ios", "linux", "netbsd",
+			"openbsd", "solaris":
+			return "/usr/local/share/juno/", nil
+		default: // js/wasm, plan9
+			return "", errors.New("user data directory not found")
+		}
+	}()
+	errpkg.CheckFatal(err, "Unable to get user data directory.")
+}
+
+func New() {
+	f := filepath.Join(Dir, "juno.yaml")
+	log.Default.With("Path", f).Info("Creating default config.")
+	// Create the juno configuration directory if it does not exist.
+	if _, err := os.Stat(Dir); os.IsNotExist(err) {
+		// notest
+		err := os.MkdirAll(Dir, 0755)
+		errpkg.CheckFatal(err, "Failed to create Config directory.")
+	}
+	data, err := yaml.Marshal(&Config{
+		Rpc:    rpcConfig{Enabled: false, Port: 8080},
+		DbPath: Dir,
+	})
+	errpkg.CheckFatal(err, "Failed to marshal Config instance to byte data.")
+	err = os.WriteFile(f, data, 0644)
+	errpkg.CheckFatal(err, "Failed to write config file.")
+}
diff --git a/internal/errpkg/errpkg.go b/internal/errpkg/errpkg.go
index 818274a0..88c4a247 100644
--- a/internal/errpkg/errpkg.go
+++ b/internal/errpkg/errpkg.go
@@ -7,22 +7,15 @@
 //  - https://github.com/golang/proposal/blob/master/design/go2draft-error-handling.md
 package errpkg
 
+// notest
 import (
 	"os"
 
 	"github.com/NethermindEth/juno/internal/log"
 )
 
-// Check checks whether an error occurred and logs it using the default
-// logger.
-func Check(err error, msg string) {
-	if err != nil {
-		log.Default.With("Error", err).Error(msg)
-	}
-}
-
-// Check checks whether an error occurred, logs it using the default
-// logger, and then
+// CheckFatal checks whether an error occurred, logs it using the default
+// logger, and then calls os.Exit(1).
 func CheckFatal(err error, msg string) {
 	if err != nil {
 		log.Default.With("Error", err).Error(msg)
diff --git a/internal/ospkg/ospkg.go b/internal/ospkg/ospkg.go
deleted file mode 100644
index adb6900a..00000000
--- a/internal/ospkg/ospkg.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Package ospkg provides constants relating to system key system
-// directories across different operating systems.
-package ospkg
-
-import (
-	"errors"
-	"os"
-	"runtime"
-
-	"github.com/NethermindEth/juno/internal/errpkg"
-)
-
-var (
-	// ConfigDir is the default root directory for user-specific
-	// configuration data.
-	//
-	// On Darwin this is $HOME/Library/Application Support, on other Unix
-	// systems it is $XDG_CONFIG_HOME, and on Windows, %APPDATA%.
-	ConfigDir,
-	// DataDir is the is the default root directory for user-specific
-	// application data.
-	//
-	// On Unix this is $XDG_DATA_HOME and on Windows, %APPDATA%.
-	DataDir,
-	// HomeDir is the current user's home directory.
-	//
-	// On Unix this is $HOME and on Windows, %USERPROFILE%.
-	HomeDir string
-)
-
-func init() {
-	var err error = nil
-	ConfigDir, err = os.UserConfigDir()
-	errpkg.CheckFatal(err, "unable to get the user config directory")
-	HomeDir, err = os.UserHomeDir()
-	errpkg.CheckFatal(err, "unable to get the user home directory")
-	DataDir, err = func() (string, error) {
-		switch runtime.GOOS {
-		case "windows":
-			// On Windows ConfigDir and DataDir share the same path. See:
-			// https://stackoverflow.com/questions/43853548/xdg-basedir-directories-for-windows
-			return ConfigDir, nil
-		case "darwin", "dragonfly", "freebsd", "illumos", "ios", "linux", "netbsd",
-			"openbsd", "solaris":
-			return "/usr/local/share/juno/", nil
-		default: // js/wasm, plan9
-			return "", errors.New("user data directory not found")
-		}
-	}()
-	errpkg.CheckFatal(err, "unable to get the user data directory")
-}
diff --git a/internal/process/process.go b/internal/process/process.go
new file mode 100644
index 00000000..a066b3f6
--- /dev/null
+++ b/internal/process/process.go
@@ -0,0 +1,91 @@
+// Package process provides a handler to manage processes.
+package process
+
+// notest
+import (
+	"context"
+	"time"
+
+	"github.com/NethermindEth/juno/internal/log"
+)
+
+// runFunc represents a function that runs a process.
+type runFunc func() error
+
+// stopFunc represents a function that stops a process.
+type stopFunc func(ctx context.Context)
+
+// process contains information and required functions of each process
+type process struct {
+	id   string
+	err  error
+	run  runFunc
+	stop stopFunc
+}
+
+// Processer defines common methods for a context processor.
+type Processer interface {
+	Add(id string, fnRun runFunc, fnStop stopFunc)
+	Run()
+	Close()
+}
+
+// Handler holds a collection of sub-processes.
+type Handler struct {
+	subprocs []*process
+}
+
+// NewHandler creates a new process.Handler.
+func NewHandler() *Handler {
+	return &Handler{}
+}
+
+// Start starts a process.
+func (p *process) Start() (err error) {
+	return p.run()
+}
+
+// Close closes all running processes.
+func (h *Handler) Close() {
+	// Clear all processes.
+	for _, proc := range h.subprocs {
+		// Set 5 second timeout.
+		ctx, cancel := context.WithDeadline(
+			context.Background(), time.Now().Add(5*time.Second))
+		proc.stop(ctx)
+		if proc.err != nil {
+			log.Default.With("Error", proc.err).Error("Error occurred while closing process.")
+		}
+		cancel()
+	}
+}
+
+// Add adds a process to the list of processes in the Handler.
+func (h *Handler) Add(id string, fnRun runFunc, fnStop stopFunc) {
+	h.subprocs = append(h.subprocs, &process{
+		id:   id,
+		run:  fnRun,
+		stop: fnStop,
+	})
+}
+
+// Run runs all the processes.
+func (h *Handler) Run() {
+	if len(h.subprocs) == 0 {
+		log.Default.Info("No processes found.")
+		return
+	}
+
+	for _, proc := range h.subprocs {
+		go func(p *process) {
+			err := p.Start()
+			if err != nil {
+				p.err = err
+				return
+			}
+		}(proc)
+	}
+
+	// Create an infinite loop.
+	select {}
+}
diff --git a/pkg/db/buckets.go b/pkg/db/buckets.go
deleted file mode 100644
index 3a49c63e..00000000
--- a/pkg/db/buckets.go
+++ /dev/null
@@ -1,1 +0,0 @@
-package db
diff --git a/pkg/db/database.go b/pkg/db/database.go
deleted file mode 100644
index 07b56efa..00000000
--- a/pkg/db/database.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package db
-
-import (
-	"github.com/NethermindEth/juno/internal/log"
-	"github.com/torquem-ch/mdbx-go/mdbx"
-)
-
-// KeyValueDatabase Represent a middleware for mdbx key-value pair database
-type KeyValueDatabase struct {
-	env  *mdbx.Env
-	path string
-}
-
-// NewKeyValueDatabase Creates a new KeyValueDatabase
-func NewKeyValueDatabase(path string, flags uint) *KeyValueDatabase {
-	log.Default.With(
-		"Path", path,
-		"Flags", flags,
-	).Info("Creating new database")
-	env, err1 := mdbx.NewEnv()
-	if err1 != nil {
-		// notest
-		log.Default.With("Error", err1).Fatalf("Cannot create environment")
-		return nil
-	}
-	// Set Flags
-	// Based on https://github.com/torquem-ch/mdbx-go/blob/96f31f483af593377e52358a079e834256d5af55/mdbx/env_test.go#L495
-	err := env.SetOption(mdbx.OptMaxDB, 1024)
-	if err != nil {
-		// notest
-		log.Default.With("Error", err).Fatalf("Cannot set Options")
-		return nil
-	}
-	const pageSize = 4096
-	err = env.SetGeometry(-1, -1, 64*1024*pageSize, -1, -1, pageSize)
-	if err != nil {
-		// notest
-		log.Default.With("Error", err1).Fatalf("Cannot set Geometry")
-		return nil
-	}
-	err = env.Open(path, flags, 0664)
-	if err != nil {
-		// notest
-		log.Default.With("Error", err1).Fatalf("Cannot open env")
-		return nil
-	}
-	return &KeyValueDatabase{
-		env:  env,
-		path: path,
-	}
-}
-
-func (d KeyValueDatabase) Has(key []byte) (has bool, err error) {
-	val, err := d.getOne(key)
-	if err != nil {
-		return false, err
-	}
-	return val != nil, nil
-}
-
-func (d KeyValueDatabase) getOne(key []byte) (val []byte, err error) {
-	var db mdbx.DBI
-	if err := d.env.View(func(txn *mdbx.Txn) error {
-		db, err = txn.OpenRoot(mdbx.Create)
-
-		if err != nil {
-			return err
-		}
-		val, err = txn.Get(db, key)
-		if mdbx.IsNotFound(err) {
-			err = nil
-			return err
-		}
-		if err != nil {
-			return err
-		}
-		return nil
-	}); err != nil {
-		return nil, err
-	}
-	return val, err
-}
-
-func (d KeyValueDatabase) Get(key []byte) ([]byte, error) {
-	log.Default.With("Key", key).Info("Getting value of provided key")
-	return d.getOne(key)
-}
-
-func (d KeyValueDatabase) Put(key, value []byte) error {
-	log.Default.With("Key", string(key)).Info("Putting value of provided key")
-	err := d.env.Update(func(txn *mdbx.Txn) (err error) {
-		log.Default.Debug("Open DBI")
-		dbi, err := txn.OpenRoot(mdbx.Create)
-
-		if err != nil {
-			return err
-		}
-		log.Default.Debug("Inserting on db")
-		return txn.Put(dbi, key, value, 0)
-	})
-	return err
-}
-
-func (d KeyValueDatabase) Delete(key []byte) error {
-	log.Default.With("Key", key).Info("Deleting value associated to provided key")
-	err := d.env.Update(func(txn *mdbx.Txn) (err error) {
-		// TODO: this error should be handled.
-		db, _ := txn.OpenRoot(mdbx.Create)
-		return txn.Del(db, key, nil)
-	})
-	return err
-}
-
-func (d KeyValueDatabase) NumberOfItems() (uint64, error) {
-	log.Default.Info("Getting the amount of items in the collection")
-	stats, err := d.env.Stat()
-	if err != nil {
-		return 0, err
-	}
-	return stats.Entries, err
-}
-
-func (d KeyValueDatabase) Begin() {
-	//TODO implement me
-}
-
-func (d KeyValueDatabase) Rollback() {
-	//TODO implement me
-}
-
-func (d KeyValueDatabase) Close() {
-	d.env.Close()
-}
diff --git a/pkg/db/db.go b/pkg/db/db.go
new file mode 100644
index 00000000..fe537983
--- /dev/null
+++ b/pkg/db/db.go
@@ -0,0 +1,175 @@
+// Package db provides a key-value database and functions related to
+// operating one.
+package db
+
+import (
+	"github.com/NethermindEth/juno/internal/log"
+	"github.com/torquem-ch/mdbx-go/mdbx"
+)
+
+// Databaser describes methods relating to an abstract key-value
+// database.
+type Databaser interface {
+	// Has returns true if the value at the provided key is in the
+	// database.
+	Has(key []byte) (bool, error)
+	// Get returns the value associated with the provided key in the
+	// database or returns an error otherwise.
+	Get(key []byte) ([]byte, error)
+	// Put inserts a key-value pair into the database.
+	Put(key, value []byte) error
+	// Delete removes a previous inserted key or returns an error
+	// otherwise.
+	Delete(key []byte) error
+	// NumberOfItems returns the number of items in the database.
+	NumberOfItems() (uint64, error)
+	// Begin starts a new transaction.
+	Begin()
+	// Rollback rollsback the database to a previous state.
+	Rollback()
+	// Close closes the environment.
+	Close()
+}
+
+// KeyValueDb represents the middleware for an MDBX key-value store.
+type KeyValueDb struct {
+	env  *mdbx.Env
+	path string
+}
+
+// New creates a new key-value database.
+func New(path string, flags uint) *KeyValueDb {
+	log.Default.With("Path", path, "Flags", flags).Info("Creating new database.")
+	env, err := mdbx.NewEnv()
+	if err != nil {
+		// notest
+		log.Default.With("Error", err).Info("Failed to initialise and allocate new mdbx.Env.")
+		return nil
+	}
+
+	// Set flags.
+	// Based on https://github.com/torquem-ch/mdbx-go/blob/96f31f483af593377e52358a079e834256d5af55/mdbx/env_test.go#L495
+	err = env.SetOption(mdbx.OptMaxDB, 1024)
+	if err != nil {
+		// notest
+		log.Default.With("Error", err).Info("Failed to set mdbx.Env options.")
+		return nil
+	}
+	const pageSize = 4096
+	err = env.SetGeometry(-1, -1, 64*1024*pageSize, -1, -1, pageSize)
+	if err != nil {
+		// notest
+		log.Default.With("Error", err).Info("Failed to set geometry.")
+		return nil
+	}
+	err = env.Open(path, flags, 0664)
+	if err != nil {
+		// notest
+		log.Default.With("Error", err).Info("Failed to open mdbx.Env.")
+		return nil
+	}
+	return &KeyValueDb{env: env, path: path}
+}
+
+// Has returns true if the value at the provided key is in the
+// database.
+func (d *KeyValueDb) Has(key []byte) (has bool, err error) {
+	val, err := d.getOne(key)
+	if err != nil {
+		log.Default.With("Error", err, "Key", string(key)).Info("Key provided does not exist.")
+		return false, err
+	}
+	return val != nil, nil
+}
+
+// getOne returns the value associated with the provided key in the
+// database or returns an error otherwise.
+func (d *KeyValueDb) getOne(key []byte) (val []byte, err error) {
+	var dbi mdbx.DBI
+	if err := d.env.View(func(txn *mdbx.Txn) error {
+		dbi, err = txn.OpenRoot(mdbx.Create)
+		if err != nil {
+			log.Default.With("Error", err).Info("Failed to open database.")
+			return err
+		}
+		val, err = txn.Get(dbi, key)
+		if err != nil {
+			if mdbx.IsNotFound(err) {
+				log.Default.With("Error", err, "Key", string(key)).Info("Failed to get value.")
+				err = nil
+				return nil
+			}
+			log.Default.With("Error", err, "Key", string(key)).Info("Failed to get value.")
+			return err
+		}
+		return nil
+	}); err != nil {
+		// Log already printed in the previous call.
+		return nil, err
+	}
+	return val, err
+}
+
+// Get returns the value associated with the provided key in the
+// database or returns an error otherwise.
+func (d *KeyValueDb) Get(key []byte) ([]byte, error) {
+	log.Default.With("Key", key).Info("Getting value using key.")
+	return d.getOne(key)
+}
+
+// Put inserts a key-value pair into the database.
+func (d *KeyValueDb) Put(key, value []byte) error {
+	log.Default.With("Key", string(key)).Info("Putting value at key.")
+	err := d.env.Update(func(txn *mdbx.Txn) error {
+		log.Default.Info("Opening the root database.")
+		dbi, err := txn.OpenRoot(mdbx.Create)
+		if err != nil {
+			log.Default.With("Error", err, "Key", string(key)).Info("Unable to open root database.")
+			return err
+		}
+		log.Default.Info("Storing item in database.")
+		return txn.Put(dbi, key, value, 0)
+	})
+	return err
+}
+
+// Delete removes a previous inserted key or returns an error otherwise.
+func (d *KeyValueDb) Delete(key []byte) error {
+	log.Default.With("Key", key).Info("Deleting value associated with key.")
+	err := d.env.Update(func(txn *mdbx.Txn) error {
+		db, err := txn.OpenRoot(mdbx.Create)
+		if err != nil {
+			log.Default.With("Error", err, "Key", string(key)).Info("Unable to open database.")
+			return err
+		}
+		err = txn.Del(db, key, nil)
+		if mdbx.IsNotFound(err) {
+			log.Default.With("Error", err, "Key", string(key)).Info("Unable to get value.")
+			return nil
+		}
+		return err
+	})
+	return err
+}
+
+// Count returns the number of items in the database.
+func (d *KeyValueDb) Count() (uint64, error) {
+	log.Default.Info("Getting the number of items in the database.")
+	stats, err := d.env.Stat()
+	if err != nil {
+		log.Default.With("Error", err).Info("Unable to get stats from env.")
+		return 0, err
+	}
+	return stats.Entries, err
+}
+
+// Begin starts a new transaction.
+func (d KeyValueDb) Begin() {}
+
+// Rollback rolls back the database to a previous state.
+func (d KeyValueDb) Rollback() {}
+
+// Close closes the environment.
+func (d *KeyValueDb) Close() {
+	d.env.Close()
+}
diff --git a/pkg/db/interface.go b/pkg/db/interface.go
deleted file mode 100644
index e4311184..00000000
--- a/pkg/db/interface.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package db
-
-type Databaser interface {
-	// Has Check that the key provided exists in the collection
-	Has(key []byte) (bool, error)
-
-	// Get Returns the value associated to the provided key or returns an error otherwise
-	Get(key []byte) ([]byte, error)
-
-	// Put Insert the key-value pair into the collection
-	Put(key, value []byte) error
-
-	// Delete Remove a previous inserted key, otherwise nothing happen
-	Delete(key []byte) error
-
-	// NumberOfItems return the number of items in the collection
-	NumberOfItems() (uint64, error)
-	Begin()
-	Rollback()
-	Close()
-}
diff --git a/pkg/rpc/client.go b/pkg/rpc/client.go
new file mode 100644
index 00000000..cdf717bb
--- /dev/null
+++ b/pkg/rpc/client.go
@@ -0,0 +1,64 @@
+package rpc
+
+import (
+	"context"
+
+	grpc "github.com/ethereum/go-ethereum/rpc"
+)
+
+// Client is a wrapper around Go Ethereum's rpc.Client struct.
+type Client struct {
+	ptr *grpc.Client
+}
+
+// Close closes the client RPC connection.
+func (c *Client) Close() {
+	c.ptr.Close()
+}
+
+// GetBlockByHash gets block information by hash.
+func (c *Client) GetBlockByHash(
+	ctx context.Context, blockHash BlockHash, requestedScope RequestedScope,
+) (*BlockResponse, error) {
+	// var res BlockResponse
+	// err := c.ptr.CallContext(
+	// 	ctx, &res, "starknet_getBlockByHash", blockHash, requestedScope)
+	// if err != nil {
+	// 	return nil, err
+	// }
+	// return &res, err
+	return &BlockResponse{}, nil
+}
+
+// GetBlockByNumber gets block information by block number.
+func (ec *Client) GetBlockByNumber(
+	ctx context.Context, blockHash BlockHash, requestedScope RequestedScope,
+) (*BlockResponse, error) {
+	// var res BlockResponse
+	// err := ec.ptr.CallContext(
+	// 	ctx, &res, "starknet_getBlockByNumber", blockHash, requestedScope)
+	// if err != nil {
+	// 	return nil, err
+	// }
+	// return &res, err
+	return &BlockResponse{}, nil
+}
+
+// NewClient creates a new rpc.Client from a Go Ethereum's rpc.Client.
+func NewClient(ptr *grpc.Client) *Client {
+	return &Client{ptr}
+}
+
+// dialContext returns a new rpc.Client or returns an error otherwise.
+func dialContext(ctx context.Context, rawUrl string) (*Client, error) {
+	c, err := grpc.DialContext(ctx, rawUrl)
+	if err != nil {
+		return nil, err
+	}
+	return NewClient(c), nil
+}
+
+// Dial connects a client to the given URL.
+func Dial(rawUrl string) (*Client, error) {
+	return dialContext(context.Background(), rawUrl)
+}
diff --git a/pkg/rpc/doc.go b/pkg/rpc/doc.go
new file mode 100644
index 00000000..539a7b40
--- /dev/null
+++ b/pkg/rpc/doc.go
@@ -0,0 +1,3 @@
+// Package rpc provides functionality related to making JSON RPC 2.0 API
+// calls supported by juno.
+package rpc
diff --git a/pkg/rpc/error.go b/pkg/rpc/error.go
new file mode 100644
index 00000000..32978ef6
--- /dev/null
+++ b/pkg/rpc/error.go
@@ -0,0 +1,60 @@
+package rpc
+
+// notest
+import "fmt"
+
+const (
+	// ErrorCodeParse is parse error code.
+	ErrorCodeParse ErrorCode = -32_700
+	// ErrorCodeInvalidRequest is invalid request error code.
+	ErrorCodeInvalidRequest ErrorCode = -32_600
+	// ErrorCodeMethodNotFound is method not found error code.
+	ErrorCodeMethodNotFound ErrorCode = -32_601
+	// ErrorCodeInvalidParams is invalid params error code.
+	ErrorCodeInvalidParams ErrorCode = -32_602
+	// ErrorCodeInternal is internal error code.
+	ErrorCodeInternal ErrorCode = -32_603
+)
+
+type (
+	// A ErrorCode by JSON-RPC 2.0.
+	ErrorCode int
+
+	// An Error is a wrapper for a JSON interface value.
+	Error struct {
+		Code    ErrorCode   `json:"code"`
+		Message string      `json:"message"`
+		Data    interface{} `json:"data,omitempty"`
+	}
+)
+
+// Error implements error interface.
+func (e *Error) Error() string {
+	return fmt.Sprintf(
+		"rpc: code: %d, message: %s, data: %+v", e.Code, e.Message, e.Data)
+}
+
+// ErrParse returns parse error.
+func ErrParse() *Error {
+	return &Error{Code: ErrorCodeParse, Message: "Parse error."}
+}
+
+// ErrInvalidRequest returns invalid request error.
+func ErrInvalidRequest() *Error {
+	return &Error{Code: ErrorCodeInvalidRequest, Message: "Invalid request."}
+}
+
+// ErrMethodNotFound returns method not found error.
+func ErrMethodNotFound() *Error {
+	return &Error{Code: ErrorCodeMethodNotFound, Message: "Method not found."}
+}
+
+// ErrInvalidParams returns invalid params error.
+func ErrInvalidParams() *Error {
+	return &Error{Code: ErrorCodeInvalidParams, Message: "Invalid params."}
+}
+
+// ErrInternal returns internal error.
+func ErrInternal() *Error {
+	return &Error{Code: ErrorCodeInternal, Message: "Internal error."}
+}
diff --git a/pkg/rpc/handle.go b/pkg/rpc/handle.go
new file mode 100644
index 00000000..68e5d250
--- /dev/null
+++ b/pkg/rpc/handle.go
@@ -0,0 +1,367 @@
+package rpc
+
+import (
+	"bytes"
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"net/http"
+	"reflect"
+	"runtime"
+	"strings"
+
+	"github.com/NethermindEth/juno/internal/log"
+	"github.com/goccy/go-json"
+	"github.com/iancoleman/strcase"
+)
+
+var (
+	contextType      = reflect.TypeOf((*context.Context)(nil)).Elem()
+	errorType        = reflect.TypeOf((*error)(nil)).Elem()
+	errorTooManyArgs = errors.New("too many arguments")
+)
+
+// Handler links a method of JSON-RPC request.
+type Handler interface {
+	ServeJSONRPC(
+		c context.Context, params *json.RawMessage,
+	) (result interface{}, err *Error)
+}
+
+// HandlerFunc type is an adapter that allows the use of Go functions as
+// JSON-RPC handlers. If f is such a function with the appropriate
+// signature, HandlerFunc(f) is a JSON-RPC.Handler that calls f.
+type HandlerFunc func(
+	c context.Context, params *json.RawMessage,
+) (result interface{}, err *Error)
+
+// ServeJSONRPC calls a function f(w, r).
+func (f HandlerFunc) ServeJSONRPC(
+	c context.Context, params *json.RawMessage,
+) (result interface{}, err *Error) {
+	// notest
+	return f(c, params)
+}
+
+// ServeHTTP provides basic JSON-RPC handling.
+func (h *HandlerJsonRpc) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	rs, batch, err := ParseRequest(r)
+	if err != nil {
+		err := SendResponse(w, []*Response{{Version: Version, Error: err}}, false)
+		if err != nil {
+			// notest
+			log.Default.With("Error", err).Info("Failed to encode error object.")
+			w.WriteHeader(http.StatusInternalServerError)
+		}
+		return
+	}
+
+	res := make([]*Response, len(rs))
+	for i, req := range rs {
+		res[i] = h.InvokeMethod(r.Context(), req)
+	}
+
+	if err := SendResponse(w, res, batch); err != nil {
+		// notest
+		log.Default.With("Error", err).Info("Failed to encode result object.")
+		w.WriteHeader(http.StatusInternalServerError)
+	}
+}
+
+// isErrorType checks whether t implements the error interface.
+func isErrorType(t reflect.Type) bool {
+	for t.Kind() == reflect.Ptr {
+		// notest
+		t = t.Elem()
+	}
+	return t.Implements(errorType)
+}
+
+// checkReturn verifies the return types. The function must return at
+// most one error and/or one other non-error value.
+func checkReturn(fnType reflect.Type) int {
+	// Create a representation for each type of the Outputs of the
+	// function.
+	outs := make([]reflect.Type, fnType.NumOut())
+	for i := 0; i < fnType.NumOut(); i++ {
+		outs[i] = fnType.Out(i)
+	}
+	if len(outs) > 2 {
+		// notest
+		return -1
+	}
+	// If an error is returned, it must be the last returned value.
+	switch {
+	case len(outs) == 1 && isErrorType(outs[0]):
+		// notest
+		return 1
+	case len(outs) == 2:
+		if isErrorType(outs[0]) || !isErrorType(outs[1]) {
+			// notest
+			return -1
+		}
+		return 1
+	}
+	// notest
+	return 0
+}
+
+// makeArgTypes composes the argTypes list.
+func makeArgTypes(fn, receiver reflect.Value) ([]reflect.Type, bool) {
+	funcType := fn.Type()
+	hasContext := false
+
+	// Skip receiver and context.Context parameter (if present).
+	firstArg := 0
+	if receiver.IsValid() {
+		firstArg++
+	}
+	if funcType.NumIn() > firstArg && funcType.In(firstArg) == contextType {
+		hasContext = true
+		firstArg++
+	}
+	// Add all remaining parameters.
+	argTypes := make([]reflect.Type, funcType.NumIn()-firstArg)
+	for i := firstArg; i < funcType.NumIn(); i++ {
+		argTypes[i-firstArg] = funcType.In(i)
+	}
+	return argTypes, hasContext
+}
+
+// parseArgs tries to parse the given arguments into an array of values
+// with the given types or the corresponding type. It returns the parsed
+// values or an error otherwise. Missing optional arguments are returned
+// as reflect.Zero values.
+func parseArgs(
+	rawMessage json.RawMessage, types []reflect.Type,
+) ([]reflect.Value, error) {
+	decoder := json.NewDecoder(bytes.NewReader(rawMessage))
+	var args []reflect.Value
+	token, err := decoder.Token()
+	switch {
+	// notest
+	case err == io.EOF || token == nil && err == nil:
+		// "params" is optional and may be empty. Also allow "params":null
+		// even though it's not in the spec because our own client used to
+		// send it.
+	case err != nil:
+		return nil, err
+	case token == json.Delim('['):
+		// Read argument array.
+		if args, err = parseArgSlice(decoder, types); err != nil {
+			return nil, err
+		}
+	default:
+		// notest
+		return nil, errors.New("non-array or struct arguments")
+	}
+	// Set any missing arguments to nil.
+	for i := len(args); i < len(types); i++ {
+		// notest
+		if types[i].Kind() != reflect.Ptr {
+			return nil, fmt.Errorf("missing value for required argument %d", i)
+		}
+		args = append(args, reflect.Zero(types[i]))
+	}
+	return args, nil
+}
+
+// parseArgSlice iterate overs each types and tries to parse the given
+// arguments to an array of values.
+func parseArgSlice(
+	decoder *json.Decoder, types []reflect.Type,
+) ([]reflect.Value, error) {
+	decoder.UseNumber()
+
+	args := make([]reflect.Value, 0, len(types))
+	for i := 0; decoder.More(); i++ {
+		if i >= len(types) {
+			err := errorTooManyArgs
+			log.Default.With("Error", err, "Requires at most ", len(types))
+			return args, err
+		}
+		val := reflect.New(types[i])
+		if err := decoder.Decode(val.Interface()); err != nil {
+			//if val.Elem().Kind() == reflect.Int64 && errType.Value == "number" {
+			//	var msgUser msgUserIntVal
+			//	err = json.Unmarshal(payload, &msgUser)
+			//	if nil == err {
+			//		msgUser.User.StrValue = strconv.Itoa(msgUser.StrValue)
+			//		user = *msgUser.User
+			//	}
+			//}
+			return args, fmt.Errorf("invalid argument %d: %v", i, err)
+		}
+		if val.IsNil() && types[i].Kind() != reflect.Ptr {
+			// notest
+			return args, fmt.Errorf("missing value for required argument %d", i)
+		}
+		log.Default.With("Kind", val.Elem().Kind()).Info("Checking kind.")
+		if val.Elem().Kind() == reflect.Struct {
+			fields := val.Elem()
+			log.Default.With("Number of fields", fields.NumField()).Debug("Parsing parameters.")
+			for i := 0; i < fields.NumField(); i++ {
+				t := fields.Type().Name()
+				tag := fields.Type().Field(i).Tag.Get("required")
+				log.Default.With("Type", t, "Tag", tag).Debug("Parsing parameter.")
+				if strings.Contains(tag, "true") && fields.Field(i).IsZero() {
+					// notest
+					// XXX: Highlight which missing field this is.
+					return args, errors.New("missing required field")
+				}
+			}
+		}
+		args = append(args, val.Elem())
+	}
+	// Read end of arguments array.
+	_, err := decoder.Token()
+	return args, err
+}
+
+// callFunc invokes the function called.
+func callFunc(
+	ctx context.Context,
+	method string,
+	args []reflect.Value,
+	fn,
+	receiver reflect.Value,
+	hasContext bool,
+	errResponsePosition int,
+) (res interface{}, errRes error) {
+	log.Default.With("Method", method).Info("Calling RPC function.")
+	// Create the argument slice.
+	fullArgs := make([]reflect.Value, 0, 2+len(args))
+	if receiver.IsValid() {
+		fullArgs = append(fullArgs, receiver)
+	}
+	if hasContext {
+		fullArgs = append(fullArgs, reflect.ValueOf(ctx))
+	}
+	fullArgs = append(fullArgs, args...)
+
+	// Catch panic while running the callback.
+	defer func() {
+		// notest
+		if err := recover(); err != nil {
+			const size = 64 << 10
+			buf := make([]byte, size)
+			buf = buf[:runtime.Stack(buf, false)]
+			log.Default.With(
+				"Method", method,
+				"Error", fmt.Sprintf("%v\n%s", err, buf),
+				"Arguments", args,
+				"Has Context", hasContext,
+				"Error Response Position", errResponsePosition,
+			).Error("RPC method crashed.")
+			errRes = errors.New("method handler crashed")
+		}
+	}()
+	// Run the function.
+	results := fn.Call(fullArgs)
+	if len(results) == 0 {
+		// notest
+		return nil, nil
+	}
+	if errResponsePosition >= 0 && !results[errResponsePosition].IsNil() {
+		// notest
+		// Method has returned non-nil error value.
+		err := results[errResponsePosition].Interface().(error)
+		return reflect.Value{}, err
+	}
+	return results[0].Interface(), nil
+}
+
+// InvokeMethod invokes JSON-RPC method.
+func (h *HandlerJsonRpc) InvokeMethod(
+	c context.Context, r *Request,
+) *Response {
+	res := NewResponse(r)
+	structToCall := reflect.ValueOf(h.StructRpc)
+
+	// Check that the struct contains the method called
+	fn, ok := structToCall.Type().MethodByName(strcase.ToCamel(r.Method))
+	if !ok {
+		// notest
+		log.Default.With("Method", r.Method).Error("Method does not exist.")
+		res.Result = nil
+		res.Error = ErrMethodNotFound()
+		return res
+	}
+
+	// Get all the types of the arguments of the function that is going to
+	// be called.
+	argTypes, hasContext := makeArgTypes(fn.Func, structToCall)
+	var args []reflect.Value
+	var err error
+	if r.Params != nil {
+		// Parse all the params received in the request and cast it to the
+		// types of the function that is going to be called.
+		args, err = parseArgs(*r.Params, argTypes)
+		if err != nil {
+			// XXX: Use more robust error handling instead of just matching
+			// against a substring.
+			if err == errorTooManyArgs {
+				log.Default.Info("Searching for overload...")
+				structToCall = reflect.ValueOf(h.StructRpc)
+
+				// Check that the struct contains the method called.
+				fn, ok = structToCall.Type().MethodByName(
+					strcase.ToCamel(r.Method) + "Opt")
+				if !ok {
+					// notest
+					log.Default.With(
+						"Method", r.Method,
+						"Params", r.Params,
+						"Error", err,
+					).Error("Invalid params.")
+					res.Result = nil
+					res.Error = ErrInvalidParams()
+					return res
+				}
+				argTypes, hasContext = makeArgTypes(fn.Func, structToCall)
+
+				args, err = parseArgs(*r.Params, argTypes)
+				if err != nil {
+					// notest
+					log.Default.With(
+						"Method", r.Method,
+						"Params", r.Params,
+						"Error", err,
+					).Error("Invalid params")
+					res.Result = nil
+					res.Error = ErrInvalidParams()
+					return res
+				}
+				log.Default.Info("Contains optional params, calling Overhead...")
+			} else {
+				// notest
+				log.Default.With(
+					"Method", r.Method,
+					"Params", r.Params,
+					"Error", err,
+				).Error("Invalid params.")
+				res.Result = nil
+				res.Error = ErrInvalidParams()
+				return res
+			}
+		}
+	}
+	// Check the return of the function and get the error position
+	// (Methods should always return and report an error).
+	errPos := checkReturn(fn.Type)
+	// Call the function
+	resFromCall, err := callFunc(
+		c, r.Method, args, fn.Func, structToCall, hasContext, errPos)
+	if err != nil {
+		// notest
+		log.Default.With(
+			"Method", r.Method, "Params", r.Params,
+		).Error("Internal error occurred while calling the function.")
+		res.Error = ErrInternal()
+		res.Result = nil
+	}
+	log.Default.With("Method", r.Method).Info("Request successful.")
+	res.Result = resFromCall
+	return res
+}
diff --git a/pkg/rpc/jsonrpc.go b/pkg/rpc/jsonrpc.go
new file mode 100644
index 00000000..af77181d
--- /dev/null
+++ b/pkg/rpc/jsonrpc.go
@@ -0,0 +1,107 @@
+package rpc
+
+import (
+	"bytes"
+	"net/http"
+	"strings"
+
+	"github.com/goccy/go-json"
+)
+
+const (
+	// Version is JSON-RPC 2.0.
+	Version = "2.0"
+
+	batchRequestKey  = '['
+	contentTypeKey   = "Content-Type"
+	contentTypeValue = "application/json"
+)
+
+type (
+	// Request represents a JSON-RPC request received by the server.
+	Request struct {
+		Version string           `json:"jsonrpc"`
+		Method  string           `json:"method"`
+		Params  *json.RawMessage `json:"params"`
+		ID      *json.RawMessage `json:"id"`
+	}
+
+	// Response represents a JSON-RPC response returned by the server.
+	Response struct {
+		Version string           `json:"jsonrpc"`
+		Result  interface{}      `json:"result,omitempty"`
+		Error   *Error           `json:"error,omitempty"`
+		ID      *json.RawMessage `json:"id,omitempty"`
+	}
+)
+
+// ParseRequest parses a HTTP request to JSON-RPC request.
+func ParseRequest(r *http.Request) ([]*Request, bool, *Error) {
+	var reqErr *Error
+
+	if !strings.HasPrefix(r.Header.Get(contentTypeKey), contentTypeValue) {
+		// notest
+		return nil, false, ErrInvalidRequest()
+	}
+
+	buf := bytes.NewBuffer(make([]byte, 0, r.ContentLength))
+	if _, err := buf.ReadFrom(r.Body); err != nil {
+		// notest
+		return nil, false, ErrInvalidRequest()
+	}
+	defer func(r *http.Request) {
+		err := r.Body.Close()
+		if err != nil {
+			// notest
+			reqErr = ErrInternal()
+		}
+	}(r)
+
+	if buf.Len() == 0 {
+		// notest
+		return nil, false, ErrInvalidRequest()
+	}
+
+	f, _, err := buf.ReadRune()
+	if err != nil {
+		// notest
+		return nil, false, ErrInvalidRequest()
+	}
+	if err := buf.UnreadRune(); err != nil {
+		// notest
+		return nil, false, ErrInvalidRequest()
+	}
+
+	var rs []*Request
+	if f != batchRequestKey {
+		var req *Request
+		if err := json.NewDecoder(buf).Decode(&req); err != nil {
+			return nil, false, ErrParse()
+		}
+		return append(rs, req), false, nil
+	}
+
+	if err := json.NewDecoder(buf).Decode(&rs); err != nil {
+		// notest
+		return nil, false, ErrParse()
+	}
+
+	return rs, true, reqErr
+}
+
+// NewResponse generates a JSON-RPC response.
+func NewResponse(r *Request) *Response {
+	return &Response{Version: r.Version, ID: r.ID}
+}
+
+// SendResponse writes JSON-RPC response.
+func SendResponse(w http.ResponseWriter, resp []*Response, batch bool) error {
+	w.Header().Set(contentTypeKey, contentTypeValue)
+	if batch || len(resp) > 1 {
+		return json.NewEncoder(w).Encode(resp)
+	} else if len(resp) == 1 {
+		return json.NewEncoder(w).Encode(resp[0])
+	}
+	// notest
+	return nil
+}
diff --git a/pkg/rpc/server.go b/pkg/rpc/server.go
new file mode 100644
index 00000000..cd506f1c
--- /dev/null
+++ b/pkg/rpc/server.go
@@ -0,0 +1,234 @@
+package rpc
+
+import (
+	"context"
+	"net/http"
+
+	"github.com/NethermindEth/juno/internal/log"
+)
+
+// Server represents the server structure
+type Server struct {
+	server http.Server
+}
+
+// HandlerRPC represents the struct that later we will apply reflection
+// to call rpc methods.
+type HandlerRPC struct{}
+
+// HandlerJsonRpc contains the JSON-RPC method functions.
+type HandlerJsonRpc struct {
+	StructRpc interface{}
+}
+
+// NewHandlerJsonRpc creates a new HandlerJsonRpc
+func NewHandlerJsonRpc(rpc interface{}) *HandlerJsonRpc {
+	return &HandlerJsonRpc{StructRpc: rpc}
+}
+
+// NewServer creates a new server.
+func NewServer(addr string) *Server {
+	mux := http.NewServeMux()
+	mux.Handle("/rpc", NewHandlerJsonRpc(HandlerRPC{}))
+	return &Server{server: http.Server{Addr: addr, Handler: mux}}
+}
+
+// ListenAndServe listens on the TCP network and handles requests on
+// incoming connections.
+func (s *Server) ListenAndServe() error {
+	// notest
+	log.Default.Info("Listening for connections .... ")
+
+	err := s.server.ListenAndServe()
+	if err != nil {
+		log.Default.With("Error", err).Error("Error occurred while trying to listen for connections.")
+		return err
+	}
+	return nil
+}
+
+// Close gracefully shuts down the server.
+func (s *Server) Close(ctx context.Context) {
+	// notest
+	select {
+	case <-ctx.Done():
+		err := s.server.Shutdown(ctx)
+		if err != nil {
+			log.Default.With("Error", err).Info("Exiting with error.")
+			return
+		}
+	default:
+	}
+}
+
+// Echo replies with the same message.
+func (HandlerRPC) Echo(c context.Context, message string) (string, error) {
+	return message, nil
+}
+
+// StarknetCall represents the handler of "starknet_call" rpc call.
+func (HandlerRPC) StarknetCall(
+	c context.Context, request FunctionCall, blockHash BlockHashOrTag,
+) (ResultCall, error) {
+	return []string{"Response", "of", "starknet_call"}, nil
+}
+
+// StarknetGetBlockByHash represent the handler for getting a block by
+// its hash.
+func (HandlerRPC) StarknetGetBlockByHash(
+	c context.Context, blockHash BlockHashOrTag,
+) (BlockResponse, error) {
+	// TODO See if is possible to support overhead without another method
+	return BlockResponse{BlockHash: string(blockHash)}, nil
+}
+
+// StarknetGetBlockByHashOpt represent the handler for getting a block
+// by its hash.
+func (HandlerRPC) StarknetGetBlockByHashOpt(
+	c context.Context, blockHash BlockHashOrTag, requestedScope RequestedScope,
+) (BlockResponse, error) {
+	// TODO See if is possible to support overhead without another method
+	return BlockResponse{
+		BlockHash:  string(blockHash),
+		ParentHash: string(requestedScope),
+	}, nil
+}
+
+// type bNumber string `json:"int,int,omitempty"`
+
+// StarknetGetBlockByNumber represent the handler for getting a block by
+// its number.
+func (HandlerRPC) StarknetGetBlockByNumber(
+	c context.Context, blockNumber interface{},
+) (BlockResponse, error) {
+	// TODO See if is possible to support overhead without another method
+	log.Default.With("Block Number", blockNumber).Info("Calling StarknetGetBlockByNumber")
+	return BlockResponse{}, nil
+}
+
+// StarknetGetBlockByNumberOpt represent the handler for getting a block
+// by its number.
+func (HandlerRPC) StarknetGetBlockByNumberOpt(
+	c context.Context, blockNumber interface{}, requestedScope RequestedScope,
+) (BlockResponse, error) {
+	// TODO See if is possible to support overhead without another method
+	return BlockResponse{}, nil
+}
+
+// StarknetGetBlockTransactionCountByHash represent the handler for
+// getting block transaction count by the blocks hash.
+func (HandlerRPC) StarknetGetBlockTransactionCountByHash(
+	c context.Context, blockHash BlockHashOrTag,
+) (BlockTransactionCount, error) {
+	return BlockTransactionCount{}, nil
+}
+
+// StarknetGetBlockTransactionCountByNumber Get the number of
+// transactions in a block given a block number (height).
+func (HandlerRPC) StarknetGetBlockTransactionCountByNumber(
+	c context.Context, blockNumber interface{},
+) (BlockTransactionCount, error) {
+	return BlockTransactionCount{}, nil
+}
+
+// StarknetGetStateUpdateByHash represent the handler for getting the
+// information about the result of executing the requested block.
+func (HandlerRPC) StarknetGetStateUpdateByHash(
+	c context.Context, blockHash BlockHashOrTag,
+) (StateUpdate, error) {
+	return StateUpdate{}, nil
+}
+
+// StarknetGetStorageAt Get the value of the storage at the given
+// address and key.
+func (HandlerRPC) StarknetGetStorageAt(
+	c context.Context,
+	contractAddress Address,
+	key Felt,
+	blockHash BlockHashOrTag,
+) (Felt, error) {
+	return "Storage", nil
+}
+
+// StarknetGetTransactionByHash Get the details and status of a
+// submitted transaction.
+func (HandlerRPC) StarknetGetTransactionByHash(
+	c context.Context, transactionHash TxnHash,
+) (Txn, error) {
+	return Txn{}, nil
+}
+
+// StarknetGetTransactionByBlockHashAndIndex Get the details of the
+// transaction given by the identified block and index in that block. If
+// no transaction is found, a null value is returned.
+func (HandlerRPC) StarknetGetTransactionByBlockHashAndIndex(
+	c context.Context, blockHash BlockHashOrTag, index uint64,
+) (Txn, error) {
+	return Txn{}, nil
+}
+
+// StarknetGetTransactionByBlockNumberAndIndex Get the details of the
+// transaction given by the identified block and index in that block. If
+// no transaction is found, null is returned.
+func (HandlerRPC) StarknetGetTransactionByBlockNumberAndIndex(
+	c context.Context, blockNumber BlockNumberOrTag, index uint64,
+) (Txn, error) {
+	return Txn{}, nil
+}
+
+// StarknetGetTransactionReceipt Get the transaction receipt by the
+// transaction hash.
+func (HandlerRPC) StarknetGetTransactionReceipt(
+	c context.Context, transactionHash TxnHash,
+) (TxnReceipt, error) {
+	return TxnReceipt{}, nil
+}
+
+// StarknetGetCode Get the code of a specific contract
+func (HandlerRPC) StarknetGetCode(
+	c context.Context, contractAddress Address,
+) (CodeResult, error) {
+	return CodeResult{}, nil
+}
+
+// StarknetBlockNumber Get the most recent accepted block number
+func (HandlerRPC) StarknetBlockNumber(c context.Context) (BlockNumber, error) {
+	return 0, nil
+}
+
+// StarknetChainId Return the currently configured StarkNet chain id
+func (HandlerRPC) StarknetChainId(c context.Context) (ChainID, error) {
+	return "Here the ChainID", nil
+}
+
+// StarknetPendingTransactions Returns the transactions in the
+// transaction pool, recognized by this sequencer.
+func (HandlerRPC) StarknetPendingTransactions(
+	c context.Context,
+) ([]Txn, error) {
+	return nil, nil
+}
+
+// StarknetProtocolVersion Returns the current starknet protocol version
+// identifier, as supported by this sequencer.
+func (HandlerRPC) StarknetProtocolVersion(
+	c context.Context,
+) (ProtocolVersion, error) {
+	return "Here the Protocol Version", nil
+}
+
+// StarknetSyncing Returns an object about the sync status, or false if
+// the node is not syncing.
+func (HandlerRPC) StarknetSyncing(
+	c context.Context,
+) (SyncStatus, error) {
+	return SyncStatus{}, nil
+}
+
+// StarknetGetEvents Returns all event objects matching the conditions
+// in the provided filter.
+func (HandlerRPC) StarknetGetEvents(
+	c context.Context, r EventRequest,
+) (EventResponse, error) {
+	return EventResponse{}, nil
+}
diff --git a/pkg/rpc/types.go b/pkg/rpc/types.go
new file mode 100644
index 00000000..2c03e2a0
--- /dev/null
+++ b/pkg/rpc/types.go
@@ -0,0 +1,258 @@
+package rpc
+
+// BlockStatus const
+const (
+	TxnHashStatus      RequestedScope = "TXN_HASH"
+	FullTxns           RequestedScope = "FULL_TXNS"
+	FullTxnAndReceipts RequestedScope = "FULL_TXN_AND_RECEIPTS"
+)
+
+const (
+	TxnStatusUnknown      TxnStatus = "UNKNOWN"
+	TxnStatusReceived     TxnStatus = "RECEIVED"
+	TxnStatusPending      TxnStatus = "PENDING"
+	TxnStatusAcceptedOnL2 TxnStatus = "ACCEPTED_ON_L2"
+	TxnStatusAcceptedOnL1 TxnStatus = "ACCEPTED_ON_L1"
+	TxnStatusRejected     TxnStatus = "REJECTED"
+)
+
+const (
+	Pending      BlockStatus = "PENDING"
+	Proven       BlockStatus = "PROVEN"
+	AcceptedOnL2 BlockStatus = "ACCEPTED_ON_L2"
+	AcceptedOnL1 BlockStatus = "ACCEPTED_ON_L1"
+	Rejected     BlockStatus = "REJECTED"
+)
+
+var (
+	FailedToReceiveTxn     = ResponseError{1, "Failed to write transaction"}
+	ContractNotFound       = ResponseError{20, "Contract not found"}
+	InvalidMessageSelector = ResponseError{21, "Invalid message selector"}
+	InvalidCallData        = ResponseError{22, "Invalid call data"}
+	InvalidStorageKey      = ResponseError{23, "Invalid storage key"}
+	InvalidBlockHash       = ResponseError{24, "Invalid block hash"}
+	InvalidTxnHash         = ResponseError{25, "Invalid transaction hash"}
+	InvalidBlockNumber     = ResponseError{26, "Invalid block number"}
+	ContractError          = ResponseError{40, "Contract error"}
+)
+
+// FunctionCall represents the details of the function call
+type FunctionCall struct {
+	// ContractAddress Is a field element of 251 bits. Represented as up to 64 hex digits
+	ContractAddress string `json:"contract_address"`
+	// EntryPointSelector Is a field element of 251 bits. Represented as up to 64 hex digits
+	EntryPointSelector string `json:"entry_point_selector"`
+	// CallData are the parameters passed to the function
+	CallData []string `json:"calldata"`
+}
+
+// BlockHash Is a field element of 251 bits. Represented as up to 64 hex digits
+type BlockHash string
+
+// BlockTag Is a tag specifying a dynamic reference to a block
+type BlockTag string
+
+// Felt represent aN field element. Represented as up to 63 hex digits and leading 4 bits zeroed.
+type Felt string
+
+// BlockNumber The block's number (its height)
+type BlockNumber uint64
+
+// ChainID StarkNet chain id, given in hex representation.
+type ChainID string
+
+// ProtocolVersion StarkNet protocol version, given in hex representation.
+type ProtocolVersion string
+
+type BlockNumberOrTag interface{}
+
+// BlockHashOrTag The hash (id) of the requested block or a block tag, for the block referencing the state or call the transaction on.
+type BlockHashOrTag string
+
+// RequestRPC Represent the calls a function in a contract and returns the return value.  Using this call will not create a transaction; hence, will not change the state
+type RequestRPC struct {
+	Request   FunctionCall `json:"request"`
+	BlockHash BlockHash    `json:"block_hash"`
+}
+
+// ResultCall Is a field element of 251 bits. Represented as up to 64 hex digits
+type ResultCall []string
+
+// BlockTransactionCount represent the number of transactions in the designated block
+type BlockTransactionCount struct {
+	TransactionCount int
+}
+
+// StateDiffItem represent a change in a single storage item
+type StateDiffItem struct {
+	// The contract address for which the state changed
+	Address Felt `json:"address"`
+	// The key of the changed value
+	Key Felt `json:"key"`
+	// THe new value applied to the given address
+	Value Felt `json:"value"`
+}
+
+// ContractItem represent a new contract added as part of the new state
+type ContractItem struct {
+	// The address of the contract code
+	Address Felt `json:"address"`
+	// The hash of the contract code
+	ContractHash Felt `json:"contractHash"`
+}
+
+// StateDiff represent the change in state applied in this block, given as a mapping of addresses to the new values and/or new contracts
+type StateDiff struct {
+	StorageDiffs []StateDiffItem `json:"storage_diffs"`
+	Contracts    []ContractItem  `json:"contracts"`
+}
+
+type StateUpdate struct {
+	BlockHash    BlockHash `json:"block_hash"`
+	NewRoot      Felt      `json:"new_root"`
+	OldRoot      Felt      `json:"old_root"`
+	AcceptedTime uint64    `json:"accepted_time"`
+	StateDiff    StateDiff `json:"state_diff"`
+}
+
+type Address Felt
+
+// TxnHash The transaction hash, as assigned in StarkNet
+type TxnHash Felt
+
+// Txn Transaction
+type Txn struct {
+	// The function the transaction invokes
+	FunctionCall
+	// The hash identifying the transaction
+	TxnHash TxnHash `json:"txn_hash"`
+}
+
+type TxnStatus string
+
+// EthAddress represent an ethereum address
+type EthAddress string
+
+type MsgToL1 struct {
+	// The target L1 address the message is sent to
+	ToAddress Felt `json:"to_address"`
+	// The Payload of the message
+	Payload Felt `json:"payload"`
+}
+
+type MsgToL2 struct {
+	// The originating L1 contract that sent the message
+	FromAddress EthAddress `json:"from_address"`
+	// The Payload of the message. The call data to the L1 handler
+	Payload []Felt `json:"payload"`
+}
+
+// EventFilter represent an event filter/query
+type EventFilter struct {
+	FromBlock BlockNumber `json:"fromBlock"`
+	ToBlock   BlockNumber `json:"toBlock"`
+	Address   Address     `json:"address"`
+	Keys      []Felt      `json:"keys"`
+}
+
+// EventContent represent the content of an Event
+type EventContent struct {
+	Keys []Felt `json:"keys"`
+	Data []Felt `json:"data"`
+}
+
+// Event represent a StarkNet Event
+type Event struct {
+	EventContent
+	FromAddress Address `json:"from_address"`
+}
+
+// EmittedEvent Represent Event information decorated with metadata on where it was emitted
+type EmittedEvent struct {
+	Event
+	BlockHash       BlockHash `json:"block_hash"`
+	TransactionHash TxnHash   `json:"transaction_hash"`
+}
+
+// TxnReceipt Receipt of the transaction
+type TxnReceipt struct {
+	TxnHash         TxnHash   `json:"txn_hash"`
+	Status          TxnStatus `json:"status"`
+	StatusData      string    `json:"status_data"`
+	MessagesSent    []MsgToL1 `json:"messages_sent"`
+	L1OriginMessage MsgToL2   `json:"l1_origin_message"`
+	Events          Event     `json:"events"`
+}
+
+// CodeResult The code and ABI for the requested contract
+type CodeResult struct {
+	Bytecode []Felt `json:"bytecode"`
+	// The ABI of the contract in JSON format. Uses the same structure as EVM ABI
+	Abi string `json:"abi"`
+}
+
+// SyncStatus Returns an object about the sync status, or false if the node is not syncing
+type SyncStatus struct {
+	// The hash of the block from which the sync started
+	StartingBlock BlockHash `json:"starting_block"`
+	// The hash of the current block being synchronized
+	CurrentBlock BlockHash `json:"current_block"`
+	// The hash of the estimated the highest block to be synchronized
+	HighestBlock BlockHash `json:"highest_block"`
+}
+
+// ResultPageRequest A request for a specific page of results
+type ResultPageRequest struct {
+	PageSize   uint64 `json:"page_size"`
+	PageNumber uint64 `json:"page_number"`
+}
+
+type BlockStatus string
+
+// ResponseError represent the possible errors of StarkNet RPC API
+type ResponseError struct {
+	Code    int    `json:"code"`
+	Message string `json:"message"`
+}
+
+type Transactions struct{}
+
+type BlockResponse struct {
+	// A field element of 251 bits. Represented as up to 64 hex digits
+	BlockHash string `json:"block_hash"`
+	// The hash of this block's parent
+	ParentHash string `json:"parent_hash"`
+	// The block number (its height)
+	BlockNumber uint64 `json:"block_number"`
+	// The status of the block
+	Status BlockStatus `json:"status"`
+	// The identity of the sequencer submitting this block
+	Sequencer string `json:"sequencer"`
+	// The new global state root
+	NewRoot Felt `json:"new_root"`
+	// The previous global state root
+	OldRoot string `json:"old_root"`
+	// When the block was accepted on L1. Formatted as...
+	AcceptedTime uint64 `json:"accepted_time"`
+	// Transactions in the Block
+	Transactions []Transactions `json:"transactions"`
+}
+
+type RequestedScope string
+
+type StarkNetHash struct{}
+
+// EventRequest represent allOf types.EventFilter and types.ResultPageRequest
+type EventRequest struct {
+	EventFilter
+	ResultPageRequest
+}
+
+// EmittedEventArray represent a set of emmited events
+type EmittedEventArray []EmittedEvent
+
+// EventResponse represent the struct of the response of events
+type EventResponse struct {
+	EmittedEventArray
+	PageNumber uint64 `json:"page_number"`
+}


Test patch:
diff --git a/test/client_test.go b/test/client_test.go
new file mode 100644
index 00000000..71cb05c3
--- /dev/null
+++ b/test/client_test.go
@@ -0,0 +1,44 @@
+package test
+
+import (
+	"context"
+	"testing"
+
+	"github.com/NethermindEth/juno/pkg/rpc"
+)
+
+const endpoint = "https://alpha4.starknet.io"
+
+func newClient() (*rpc.Client, error) {
+	return rpc.Dial(endpoint)
+}
+
+func TestClient_GetBlockByHash(t *testing.T) {
+	c, err := newClient()
+	if err != nil {
+		t.Errorf("Failed to initialise new client.")
+	}
+	defer c.Close()
+	blockHash := rpc.BlockHash("latest")
+	requestedScope := rpc.RequestedScope("scope")
+	response, err := c.GetBlockByHash(context.Background(), blockHash, requestedScope)
+	if err != nil {
+		t.Error(err)
+	}
+	t.Log(response)
+}
+
+func TestClient_GetBlockByNumber(t *testing.T) {
+	c, err := newClient()
+	if err != nil {
+		t.Errorf("Failed to initialise new client.")
+	}
+	defer c.Close()
+	blockHash := rpc.BlockHash("latest")
+	requestedScope := rpc.RequestedScope("scope")
+	response, err := c.GetBlockByNumber(context.Background(), blockHash, requestedScope)
+	if err != nil {
+		t.Error(err)
+	}
+	t.Log(response)
+}
diff --git a/test/config_test.go b/test/config_test.go
new file mode 100644
index 00000000..6809f2be
--- /dev/null
+++ b/test/config_test.go
@@ -0,0 +1,23 @@
+package test
+
+import (
+	"os"
+	"path/filepath"
+	"testing"
+
+	"github.com/NethermindEth/juno/internal/config"
+	"gopkg.in/yaml.v2"
+)
+
+func TestConfig(t *testing.T) {
+	config.New()
+	f, err := os.ReadFile(filepath.Join(config.Dir, "juno.yaml"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	var cfg *config.Config
+	err = yaml.Unmarshal(f, &cfg)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/test/database_test.go b/test/db_test.go
similarity index 70%
rename from test/database_test.go
rename to test/db_test.go
index 46d6f698..1907e1ef 100644
--- a/test/database_test.go
+++ b/test/db_test.go
@@ -4,30 +4,27 @@ import (
 	"strconv"
 	"testing"
 
-	log "github.com/sirupsen/logrus"
-
 	"github.com/NethermindEth/juno/pkg/db"
 )
 
 var keyValueTest = map[string]string{}
 
 func init() {
-	log.SetLevel(log.ErrorLevel)
 	for i := 0; i < 350; i++ {
 		val := strconv.Itoa(i)
 		keyValueTest["key"+val] = "value" + val
 	}
 }
 
-// setupDatabaseForTest creates a new Database for Tests
-func setupDatabaseForTest(path string) *db.KeyValueDatabase {
-	return db.NewKeyValueDatabase(path, 0)
+// setupDatabaseForTest creates a new KVDatabase for Tests
+func setupDatabaseForTest(path string) *db.KeyValueDb {
+	return db.New(path, 0)
 }
 
 // TestAddKey Check that a single value is inserted without error
 func TestAddKey(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
-	err := db.Put([]byte("key"), []byte("value"))
+	database := setupDatabaseForTest(t.TempDir())
+	err := database.Put([]byte("key"), []byte("value"))
 	if err != nil {
 		t.Log(err)
 		t.Fail()
@@ -36,8 +33,8 @@ func TestAddKey(t *testing.T) {
 
 // TestNumberOfItems Checks that in every moment the collection contains the right amount of items
 func TestNumberOfItems(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
-	n, err := db.NumberOfItems()
+	database := setupDatabaseForTest(t.TempDir())
+	n, err := database.Count()
 	if err != nil {
 		t.Log(err)
 		t.Fail()
@@ -49,14 +46,14 @@ func TestNumberOfItems(t *testing.T) {
 		return
 	}
 	for k, v := range keyValueTest {
-		err := db.Put([]byte(k), []byte(v))
+		err := database.Put([]byte(k), []byte(v))
 		if err != nil {
 			t.Log(err)
 			t.Fail()
 			return
 		}
 	}
-	n, err = db.NumberOfItems()
+	n, err = database.Count()
 	if err != nil {
 		t.Log(err)
 		t.Fail()
@@ -70,16 +67,16 @@ func TestNumberOfItems(t *testing.T) {
 
 // TestAddMultipleKeys Checks that after insert some keys the collection contains the right amount of items
 func TestAddMultipleKeys(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
+	database := setupDatabaseForTest(t.TempDir())
 	for k, v := range keyValueTest {
-		err := db.Put([]byte(k), []byte(v))
+		err := database.Put([]byte(k), []byte(v))
 		if err != nil {
 			t.Log(err)
 			t.Fail()
 			return
 		}
 	}
-	n, err := db.NumberOfItems()
+	n, err := database.Count()
 	if err != nil {
 		t.Log(err)
 		t.Fail()
@@ -93,15 +90,15 @@ func TestAddMultipleKeys(t *testing.T) {
 
 // TestHasKey Check that one key exist after insertion
 func TestHasKey(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
+	database := setupDatabaseForTest(t.TempDir())
 	goodKey := []byte("good_key")
-	err := db.Put(goodKey, []byte("value"))
+	err := database.Put(goodKey, []byte("value"))
 	if err != nil {
 		t.Log(err)
 		t.Fail()
 		return
 	}
-	has, err := db.Has(goodKey)
+	has, err := database.Has(goodKey)
 	if err != nil {
 		t.Log(err)
 		t.Fail()
@@ -116,16 +113,16 @@ func TestHasKey(t *testing.T) {
 
 // TestHasNotKey Check that a key don't exist
 func TestHasNotKey(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
+	database := setupDatabaseForTest(t.TempDir())
 	goodKey := []byte("good_key")
 	badKey := []byte("bad_key")
-	err := db.Put(goodKey, []byte("value"))
+	err := database.Put(goodKey, []byte("value"))
 	if err != nil {
 		t.Log(err)
 		t.Fail()
 		return
 	}
-	has2, err := db.Has(badKey)
+	has2, err := database.Has(badKey)
 	if err != nil {
 		t.Log(err)
 		t.Fail()
@@ -139,16 +136,16 @@ func TestHasNotKey(t *testing.T) {
 
 // TestGetKey Check that a key is property retrieved
 func TestGetKey(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
+	database := setupDatabaseForTest(t.TempDir())
 	goodKey := []byte("good_key")
 	goodValue := []byte("value")
-	err := db.Put(goodKey, goodValue)
+	err := database.Put(goodKey, goodValue)
 	if err != nil {
 		t.Log(err)
 		t.Fail()
 		return
 	}
-	val, err := db.Get(goodKey)
+	val, err := database.Get(goodKey)
 	if err != nil {
 		t.Log(err)
 		t.Fail()
@@ -162,16 +159,16 @@ func TestGetKey(t *testing.T) {
 
 // TestGetNotKey Check that a key don't exist and what happen if it doesn't exist
 func TestGetNotKey(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
+	database := setupDatabaseForTest(t.TempDir())
 	goodKey := []byte("good_key")
 	goodValue := []byte("value")
 	badKey := []byte("bad_key")
-	err := db.Put(goodKey, goodValue)
+	err := database.Put(goodKey, goodValue)
 	if err != nil {
 		t.Log(err)
 		t.Fail()
 	}
-	key, err := db.Get(badKey)
+	key, err := database.Get(badKey)
 	if err != nil {
 		t.Log(err)
 		t.Fail()
@@ -185,54 +182,58 @@ func TestGetNotKey(t *testing.T) {
 }
 
 func TestDelete(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
+	database := setupDatabaseForTest(t.TempDir())
 	goodKey := []byte("good_key")
 	goodValue := []byte("value")
-	err := db.Put(goodKey, goodValue)
+	err := database.Put(goodKey, goodValue)
 	if err != nil {
 		t.Log(err)
 		t.Fail()
 	}
-	err = db.Delete(goodKey)
+	err = database.Delete(goodKey)
 	if err != nil {
 		t.Log(err)
 		t.Fail()
 		return
 	}
-	key, err := db.Has(goodKey)
+	key, err := database.Has(goodKey)
 	if key {
 		t.Log(err)
 		t.Fail()
 		return
 	}
+	err = database.Delete(goodKey)
+	if err != nil {
+		t.Log(err)
+		t.Fail()
+	}
 }
 
 func TestBegin(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
-	db.Begin()
+	database := setupDatabaseForTest(t.TempDir())
+	database.Begin()
 }
 func TestRollBack(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
-	db.Rollback()
+	database := setupDatabaseForTest(t.TempDir())
+	database.Rollback()
 }
 func TestClose(t *testing.T) {
-	db := setupDatabaseForTest(t.TempDir())
-	db.Close()
+	database := setupDatabaseForTest(t.TempDir())
+	database.Close()
 }
 
 // BenchmarkEntriesInDatabase Benchmark the entry of key-value pairs to the db
 func BenchmarkEntriesInDatabase(b *testing.B) {
-	log.SetLevel(log.ErrorLevel)
-	db := setupDatabaseForTest(b.TempDir())
+	database := setupDatabaseForTest(b.TempDir())
 	for i := 0; i < b.N; i++ {
 		val := []byte(strconv.Itoa(i))
-		err := db.Put(val, val)
+		err := database.Put(val, val)
 		if err != nil {
 			b.Error("Benchmarking fails, error storing values")
 			return
 		}
 	}
-	n, err := db.NumberOfItems()
+	n, err := database.Count()
 	if err != nil {
 		b.Errorf("Benchmarking fails, error getting the number of items: %s\n", err)
 		b.Fail()
@@ -248,16 +249,16 @@ func BenchmarkEntriesInDatabase(b *testing.B) {
 
 // BenchmarkConsultsToDatabase Benchmark the consult to a db
 func BenchmarkConsultsToDatabase(b *testing.B) {
-	db := setupDatabaseForTest(b.TempDir())
+	database := setupDatabaseForTest(b.TempDir())
 	for i := 0; i < b.N; i++ {
 		val := []byte(strconv.Itoa(i))
-		err := db.Put(val, val)
+		err := database.Put(val, val)
 		if err != nil {
 			b.Error("Benchmarking fails, error storing values")
 			b.Fail()
 			return
 		}
-		get, err := db.Get(val)
+		get, err := database.Get(val)
 		if err != nil {
 			b.Errorf("Benchmarking fails, error getting values: %s\n", err)
 			b.Fail()
diff --git a/test/rpc_test.go b/test/rpc_test.go
new file mode 100644
index 00000000..5fcea351
--- /dev/null
+++ b/test/rpc_test.go
@@ -0,0 +1,82 @@
+package test
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+	"net/http/httptest"
+	"os"
+	"testing"
+	"time"
+
+	"github.com/NethermindEth/juno/pkg/rpc"
+)
+
+func getServerHandler() *rpc.HandlerJsonRpc {
+	return rpc.NewHandlerJsonRpc(rpc.HandlerRPC{})
+}
+
+type rpcTest struct {
+	Request  string `json:"request"`
+	Response string `json:"response"`
+}
+
+func testServer(t *testing.T, tests []rpcTest) {
+	server := getServerHandler()
+
+	for i, v := range tests {
+		req := httptest.NewRequest(http.MethodPost, "/rpc", bytes.NewBuffer([]byte(v.Request)))
+		w := httptest.NewRecorder()
+		req.Header.Set("Content-Type", "application/json")
+		server.ServeHTTP(w, req)
+		res := w.Result()
+		data, err := io.ReadAll(res.Body)
+		if err != nil {
+			t.Errorf("expected error to be nil got %v", err)
+			_ = res.Body.Close()
+		}
+		s := string(data)
+		if s != v.Response {
+			t.Errorf("expected %v, got %v", v.Response, string(data))
+			_ = res.Body.Close()
+		}
+		t.Log("Executed test ", i)
+	}
+}
+
+func TestRPCServer(t *testing.T) {
+	jsonFile, err := os.Open("rpc_tests.json")
+	// if we os.Open returns an error then handle it
+	if err != nil {
+		fmt.Println(err)
+	}
+	fmt.Println("Successfully Opened users.json")
+	// defer the closing of our jsonFile so that we can parse it later on
+	defer jsonFile.Close()
+	// read our opened jsonFile as a byte array.
+	byteValue, _ := io.ReadAll(jsonFile)
+
+	// we initialize our Users array
+	var tests []rpcTest
+
+	// we unmarshal our byteArray which contains our
+	// jsonFile's content into 'users' which we defined above
+	err = json.Unmarshal(byteValue, &tests)
+	if err != nil {
+		return
+	}
+	testServer(t, tests)
+}
+
+func TestServer(t *testing.T) {
+	server := rpc.NewServer(":8080")
+	go func() {
+		_ = server.ListenAndServe()
+	}()
+	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2*time.Second))
+	server.Close(ctx)
+	cancel()
+}
diff --git a/test/rpc_tests.json b/test/rpc_tests.json
new file mode 100644
index 00000000..8791f1b5
--- /dev/null
+++ b/test/rpc_tests.json
@@ -0,0 +1,142 @@
+[
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"345\",\"method\":\"echo\",\"params\":[\"Hello Echo\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":\"Hello Echo\",\"id\":\"345\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"345\",\"method\":\"starknet_getEvents\",\"params\":[{\"fromBlock\":0,\"toBlock\":0,\"address\":\"\",\"keys\":null,\"page_size\":0,\"page_number\":0}]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"EmittedEventArray\":null,\"page_number\":0},\"id\":\"345\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"34\",\"method\":\"starknet_call\",\"params\":[{\"callata\":[\"0x1234\"],\"contract_address\":\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\",\n\"entry_point_selector\":\"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320\"}, \"latest\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":[\"Response\",\"of\",\"starknet_call\"],\"id\":\"34\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"34\",\"method\":\"starknet_call\",\"params\":[{\"calldata\":[\"0x1234\"],\"contract_address\":\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\",\n\"entry_point_selector\":\"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320\"}, \"latest\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":[\"Response\",\"of\",\"starknet_call\"],\"id\":\"34\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"34\",\"method\":\"starknet_call\",\"params\":9{[{\"calldata\":[\"0x1234\"],\"contract_address\":\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\",\n\"entry_point_selector\":\"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320\"}, \"latest\"]}}",
+    "response": "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32700,\"message\":\"Parse error.\"}}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"starknet_getBlockByHash\",\"params\":[\"pending\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"pending\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"0\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"2\",\"method\":\"starknet_getBlockByHash\",\"params\":[\"pending\",\"TXN_HASH\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"pending\",\"parent_hash\":\"TXN_HASH\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"2\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"method\":\"starknet_getBlockByNumber\",\"params\":[\"pending\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"1\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\":\"starknet_getBlockByNumber\",\"params\":[\"pending\",\"TXN_HASH\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"3\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"4\",\"method\":\"starknet_getBlockByHash\",\"params\":[\"latest\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"latest\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"4\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"5\",\"method\":\"starknet_getBlockByNumber\",\"params\":[\"latest\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"5\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"6\",\"method\":\"starknet_getBlockByHash\",\"params\":[\"latest\",\"TXN_HASH\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"latest\",\"parent_hash\":\"TXN_HASH\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"6\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"7\",\"method\":\"starknet_getBlockByNumber\",\"params\":[\"latest\",\"TXN_HASH\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"7\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"8\",\"method\":\"starknet_getBlockByHash\",\"params\":[\"latest\",\"FULL_TXNS\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"latest\",\"parent_hash\":\"FULL_TXNS\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"8\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"9\",\"method\":\"starknet_getBlockByNumber\",\"params\":[\"latest\",\"FULL_TXNS\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"9\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"10\",\"method\":\"starknet_getBlockByHash\",\"params\":[\"latest\",\"FULL_TXN_AND_RECEIPTS\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"latest\",\"parent_hash\":\"FULL_TXN_AND_RECEIPTS\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"10\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"11\",\"method\":\"starknet_getBlockByNumber\",\"params\":[\"latest\",\"FULL_TXN_AND_RECEIPTS\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"11\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"39\",\"method\":\"starknet_protocolVersion\"}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":\"Here the Protocol Version\",\"id\":\"39\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"40\",\"method\":\"starknet_syncing\"}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"starting_block\":\"\",\"current_block\":\"\",\"highest_block\":\"\"},\"id\":\"40\"}\n"
+  },
+  {
+    "request": "[{\"jsonrpc\":\"2.0\",\"id\":\"34\",\"method\":\"starknet_call\",\"params\":[{\"calldata\":[\"0x1234\"],\"contract_address\":\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\",\n\"entry_point_selector\":\"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320\"}, \"latest\"]},\n{\"jsonrpc\":\"2.0\",\"id\":\"35\",\"method\":\"starknet_call\",\"params\":[{\"calldata\":[\"0x1234\"],\"contract_address\":\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\",\n\"entry_point_selector\":\"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320\"}, \"pending\"]}]",
+    "response": "[{\"jsonrpc\":\"2.0\",\"result\":[\"Response\",\"of\",\"starknet_call\"],\"id\":\"34\"},{\"jsonrpc\":\"2.0\",\"result\":[\"Response\",\"of\",\"starknet_call\"],\"id\":\"35\"}]\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"12\",\"method\":\"starknet_getBlockByHash\",\"params\":[\"0x7d328a71faf48c5c3857e99f20a77b18522480956d1cd5bff1ff2df3c8b427b\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"0x7d328a71faf48c5c3857e99f20a77b18522480956d1cd5bff1ff2df3c8b427b\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"12\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"13\",\"method\":\"starknet_getBlockByNumber\",\"params\":[41000]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"\",\"parent_hash\":\"\",\"block_number\":0,\"status\":\"\",\"sequencer\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"transactions\":null},\"id\":\"13\"}\n"
+  },
+  {
+    "request": "[{\"jsonrpc\":\"2.0\",\"id\":\"14\",\"method\":\"starknet_getStateUpdateByHash\",\"params\":[\"latest\"]},{\"jsonrpc\":\"2.0\",\"id\":\"15\",\"method\":\"starknet_getStateUpdateByHash\",\"params\":[\"0x7d328a71faf48c5c3857e99f20a77b18522480956d1cd5bff1ff2df3c8b427b\"]}]",
+    "response": "[{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"state_diff\":{\"storage_diffs\":null,\"contracts\":null}},\"id\":\"14\"},{\"jsonrpc\":\"2.0\",\"result\":{\"block_hash\":\"\",\"new_root\":\"\",\"old_root\":\"\",\"accepted_time\":0,\"state_diff\":{\"storage_diffs\":null,\"contracts\":null}},\"id\":\"15\"}]\n"
+  },
+  {
+    "request": "[{\"jsonrpc\":\"2.0\",\"id\":\"16\",\"method\":\"starknet_getStorageAt\",\"params\":[\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\", \"0x0206F38F7E4F15E87567361213C28F235CCCDAA1D7FD34C9DB1DFE9489C6A091\", \"latest\"]},{\"jsonrpc\":\"2.0\",\"id\":\"17\",\"method\":\"starknet_getStorageAt\",\"params\":[\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\", \"0x0206F38F7E4F15E87567361213C28F235CCCDAA1D7FD34C9DB1DFE9489C6A091\", \"pending\"]},{\"jsonrpc\":\"2.0\",\"id\":\"18\",\"method\":\"starknet_getStorageAt\",\"params\":[\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\", \"0x0206F38F7E4F15E87567361213C28F235CCCDAA1D7FD34C9DB1DFE9489C6A091\", \"0x3871c8a0c3555687515a07f365f6f5b1d8c2ae953f7844575b8bde2b2efed27\"]}]'",
+    "response": "[{\"jsonrpc\":\"2.0\",\"result\":\"Storage\",\"id\":\"16\"},{\"jsonrpc\":\"2.0\",\"result\":\"Storage\",\"id\":\"17\"},{\"jsonrpc\":\"2.0\",\"result\":\"Storage\",\"id\":\"18\"}]\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"19\",\"method\":\"starknet_getTransactionByHash\",\"params\":[\"0x74ec6667e6057becd3faff77d9ab14aecf5dde46edb7c599ee771f70f9e80ba\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"contract_address\":\"\",\"entry_point_selector\":\"\",\"calldata\":null,\"txn_hash\":\"\"},\"id\":\"19\"}\n"
+  },
+  {
+    "request": "[{\"jsonrpc\":\"2.0\",\"id\":\"20\",\"method\":\"starknet_getTransactionByBlockHashAndIndex\",\"params\":[\"latest\", 0]},\n{\"jsonrpc\":\"2.0\",\"id\":\"21\",\"method\":\"starknet_getTransactionByBlockNumberAndIndex\",\"params\":[\"latest\", 0]},\n{\"jsonrpc\":\"2.0\",\"id\":\"22\",\"method\":\"starknet_getTransactionByBlockHashAndIndex\",\"params\":[\"pending\", 0]},\n{\"jsonrpc\":\"2.0\",\"id\":\"23\",\"method\":\"starknet_getTransactionByBlockNumberAndIndex\",\"params\":[\"pending\", 0]},\n{\"jsonrpc\":\"2.0\",\"id\":\"24\",\"method\":\"starknet_getTransactionByBlockHashAndIndex\",\"params\":[\"0x3871c8a0c3555687515a07f365f6f5b1d8c2ae953f7844575b8bde2b2efed27\", 4]},\n{\"jsonrpc\":\"2.0\",\"id\":\"25\",\"method\":\"starknet_getTransactionByBlockNumberAndIndex\",\"params\":[21348, 4]}]",
+    "response": "[{\"jsonrpc\":\"2.0\",\"result\":{\"contract_address\":\"\",\"entry_point_selector\":\"\",\"calldata\":null,\"txn_hash\":\"\"},\"id\":\"20\"},{\"jsonrpc\":\"2.0\",\"result\":{\"contract_address\":\"\",\"entry_point_selector\":\"\",\"calldata\":null,\"txn_hash\":\"\"},\"id\":\"21\"},{\"jsonrpc\":\"2.0\",\"result\":{\"contract_address\":\"\",\"entry_point_selector\":\"\",\"calldata\":null,\"txn_hash\":\"\"},\"id\":\"22\"},{\"jsonrpc\":\"2.0\",\"result\":{\"contract_address\":\"\",\"entry_point_selector\":\"\",\"calldata\":null,\"txn_hash\":\"\"},\"id\":\"23\"},{\"jsonrpc\":\"2.0\",\"result\":{\"contract_address\":\"\",\"entry_point_selector\":\"\",\"calldata\":null,\"txn_hash\":\"\"},\"id\":\"24\"},{\"jsonrpc\":\"2.0\",\"result\":{\"contract_address\":\"\",\"entry_point_selector\":\"\",\"calldata\":null,\"txn_hash\":\"\"},\"id\":\"25\"}]\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"22\",\"method\":\"starknet_getTransactionByBlockNumberAndIndex\",\"params\":[\"pending\", 0]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"contract_address\":\"\",\"entry_point_selector\":\"\",\"calldata\":null,\"txn_hash\":\"\"},\"id\":\"22\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"26\",\"method\":\"starknet_getTransactionReceipt\",\"params\":[\"0x74ec6667e6057becd3faff77d9ab14aecf5dde46edb7c599ee771f70f9e80ba\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"txn_hash\":\"\",\"status\":\"\",\"status_data\":\"\",\"messages_sent\":null,\"l1_origin_message\":{\"from_address\":\"\",\"payload\":null},\"events\":{\"keys\":null,\"data\":null,\"from_address\":\"\"}},\"id\":\"26\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"27\",\"method\":\"starknet_getCode\",\"params\":[\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\"]}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"bytecode\":null,\"abi\":\"\"},\"id\":\"27\"}\n"
+  },
+  {
+    "request": "[{\"jsonrpc\":\"2.0\",\"id\":\"28\",\"method\":\"starknet_getBlockTransactionCountByHash\",\"params\":[\"latest\"]},\n{\"jsonrpc\":\"2.0\",\"id\":\"29\",\"method\":\"starknet_getBlockTransactionCountByNumber\",\"params\":[\"latest\"]},\n{\"jsonrpc\":\"2.0\",\"id\":\"30\",\"method\":\"starknet_getBlockTransactionCountByHash\",\"params\":[\"pending\"]},\n{\"jsonrpc\":\"2.0\",\"id\":\"31\",\"method\":\"starknet_getBlockTransactionCountByNumber\",\"params\":[\"pending\"]},\n{\"jsonrpc\":\"2.0\",\"id\":\"32\",\"method\":\"starknet_getBlockTransactionCountByHash\",\"params\":[\"0x3871c8a0c3555687515a07f365f6f5b1d8c2ae953f7844575b8bde2b2efed27\"]},\n{\"jsonrpc\":\"2.0\",\"id\":\"33\",\"method\":\"starknet_getBlockTransactionCountByNumber\",\"params\":[21348]}]",
+    "response": "[{\"jsonrpc\":\"2.0\",\"result\":{\"TransactionCount\":0},\"id\":\"28\"},{\"jsonrpc\":\"2.0\",\"result\":{\"TransactionCount\":0},\"id\":\"29\"},{\"jsonrpc\":\"2.0\",\"result\":{\"TransactionCount\":0},\"id\":\"30\"},{\"jsonrpc\":\"2.0\",\"result\":{\"TransactionCount\":0},\"id\":\"31\"},{\"jsonrpc\":\"2.0\",\"result\":{\"TransactionCount\":0},\"id\":\"32\"},{\"jsonrpc\":\"2.0\",\"result\":{\"TransactionCount\":0},\"id\":\"33\"}]\n"
+  },
+  {
+    "request": "[{\"jsonrpc\":\"2.0\",\"id\":\"34\",\"method\":\"starknet_call\",\"params\":[{\"calldata\":[\"0x1234\"],\"contract_address\":\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\",\n\"entry_point_selector\":\"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320\"}, \"latest\"]},\n{\"jsonrpc\":\"2.0\",\"id\":\"35\",\"method\":\"starknet_call\",\"params\":[{\"calldata\":[\"0x1234\"],\"contract_address\":\"0x6fbd460228d843b7fbef670ff15607bf72e19fa94de21e29811ada167b4ca39\",\n\"entry_point_selector\":\"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320\"}, \"pending\"]}]",
+    "response": "[{\"jsonrpc\":\"2.0\",\"result\":[\"Response\",\"of\",\"starknet_call\"],\"id\":\"34\"},{\"jsonrpc\":\"2.0\",\"result\":[\"Response\",\"of\",\"starknet_call\"],\"id\":\"35\"}]\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"36\",\"method\":\"starknet_blockNumber\"}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":0,\"id\":\"36\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"37\",\"method\":\"starknet_chainId\"}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":\"Here the ChainID\",\"id\":\"37\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"38\",\"method\":\"starknet_pendingTransactions\"}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":null,\"id\":\"38\"}\n"
+  },
+  {
+    "request": "{\"jsonrpc\":\"2.0\",\"id\":\"40\",\"method\":\"starknet_syncing\"}",
+    "response": "{\"jsonrpc\":\"2.0\",\"result\":{\"starting_block\":\"\",\"current_block\":\"\",\"highest_block\":\"\"},\"id\":\"40\"}\n"
+  }
+]
\ No newline at end of file