Compare commits

...

6 Commits

Author SHA1 Message Date
Jim McDonald
12bd0e303f Add store type and location to wallet information where possible 2020-02-08 23:57:34 +00:00
Jim McDonald
502d9a9bd0 Update dependencies 2020-02-07 14:12:08 +00:00
Jim McDonald
6f863bce9a Allow creation of multiple validator deposits in one command 2020-02-06 15:10:50 +00:00
Jim McDonald
d1d54989c2 Add voluntary exit 2020-02-05 13:04:09 +00:00
Jim McDonald
eb813475c0 Add voluntary exit 2020-01-29 23:45:40 +00:00
Jim McDonald
93e828f256 Update dependencies 2020-01-13 21:15:11 +00:00
12 changed files with 616 additions and 145 deletions

View File

@@ -14,15 +14,20 @@
package cmd
import (
"context"
"errors"
"fmt"
"os"
"regexp"
"sort"
"strings"
"time"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
types "github.com/wealdtech/go-eth2-types"
"google.golang.org/grpc"
wallet "github.com/wealdtech/go-eth2-wallet"
wtypes "github.com/wealdtech/go-eth2-wallet-types"
@@ -33,6 +38,10 @@ var quiet bool
var verbose bool
var debug bool
// For transaction commands
var wait bool
var generate bool
// Root variables, present for all commands
var rootStore string
var rootAccount string
@@ -40,6 +49,8 @@ var rootStorePassphrase string
var rootWalletPassphrase string
var rootAccountPassphrase string
var eth2GRPCConn *grpc.ClientConn
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: "ethdo",
@@ -69,12 +80,29 @@ func persistentPreRun(cmd *cobra.Command, args []string) {
rootWalletPassphrase = viper.GetString("walletpassphrase")
rootAccountPassphrase = viper.GetString("passphrase")
// ...lots of commands have transaction-related flags (e.g.) 'wait'
// as options but we want to bind them to this particular command and
// this is the first chance we get
if cmd.Flags().Lookup("wait") != nil {
err := viper.BindPFlag("wait", cmd.Flags().Lookup("wait"))
errCheck(err, "Failed to set wait option")
}
wait = viper.GetBool("wait")
if cmd.Flags().Lookup("generate") != nil {
err := viper.BindPFlag("generate", cmd.Flags().Lookup("generate"))
errCheck(err, "Failed to set generate option")
}
generate = viper.GetBool("generate")
if quiet && verbose {
die("Cannot supply both quiet and verbose flags")
}
if quiet && debug {
die("Cannot supply both quiet and debug flags")
}
if generate && wait {
die("Cannot supply both generate and wait flags")
}
// Set up our wallet store
err := wallet.SetStore(rootStore, []byte(rootStorePassphrase))
@@ -130,6 +158,14 @@ func init() {
if err := viper.BindPFlag("debug", RootCmd.PersistentFlags().Lookup("debug")); err != nil {
panic(err)
}
RootCmd.PersistentFlags().String("connection", "", "connection to Ethereum 2 node via GRPC")
if err := viper.BindPFlag("connection", RootCmd.PersistentFlags().Lookup("connection")); err != nil {
panic(err)
}
RootCmd.PersistentFlags().Duration("timeout", 10*time.Second, "the time after which a network request will be considered failed. Increase this if you are running on an error-prone, high-latency or low-bandwidth connection")
if err := viper.BindPFlag("timeout", RootCmd.PersistentFlags().Lookup("timeout")); err != nil {
panic(err)
}
}
// initConfig reads in config file and ENV variables if set.
@@ -230,17 +266,79 @@ func accountFromPath(path string) (wtypes.Account, error) {
return wallet.AccountByName(accountName)
}
func sign(path string, data []byte, domain uint64) (types.Signature, error) {
assert(rootAccountPassphrase != "", "--passphrase is required")
// accountsFromPath obtains 0 or more accounts given a path specification.
func accountsFromPath(path string) ([]wtypes.Account, error) {
accounts := make([]wtypes.Account, 0)
// Quick check to see if it's a single account
account, err := accountFromPath(path)
if err == nil && account != nil {
accounts = append(accounts, account)
return accounts, nil
}
wallet, err := walletFromPath(path)
if err != nil {
return nil, err
}
err = account.Unlock([]byte(rootAccountPassphrase))
_, accountSpec, err := walletAndAccountNamesFromPath(path)
if err != nil {
return nil, err
}
defer account.Lock()
if accountSpec == "" {
accountSpec = "^.*$"
} else {
accountSpec = fmt.Sprintf("^%s$", accountSpec)
}
re := regexp.MustCompile(accountSpec)
for account := range wallet.Accounts() {
if re.Match([]byte(account.Name())) {
accounts = append(accounts, account)
}
}
// Tidy up accounts by name.
sort.Slice(accounts, func(i, j int) bool {
return accounts[i].Name() < accounts[j].Name()
})
return accounts, nil
}
// sign signs data in a domain.
func sign(account wtypes.Account, data []byte, domain uint64) (types.Signature, error) {
if !account.IsUnlocked() {
return nil, errors.New("account must be unlocked to sign")
}
return account.Sign(data, domain)
}
// addTransactionFlags adds flags used in all transactions.
func addTransactionFlags(cmd *cobra.Command) {
cmd.Flags().Bool("generate", false, "Do not send the transaction; generate and output as a hex string only")
cmd.Flags().Bool("wait", false, "wait for the transaction to be mined before returning")
}
// connect connects to an Ethereum 2 endpoint.
func connect() error {
connection := ""
if viper.GetString("connection") != "" {
connection = viper.GetString("connection")
}
if connection == "" {
return errors.New("no connection")
}
outputIf(debug, fmt.Sprintf("Connecting to %s", connection))
opts := []grpc.DialOption{grpc.WithInsecure()}
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
var err error
eth2GRPCConn, err = grpc.DialContext(ctx, connection, opts...)
return err
}

View File

@@ -16,6 +16,7 @@ package cmd
import (
"fmt"
"os"
"strings"
"github.com/prysmaticlabs/go-ssz"
"github.com/spf13/cobra"
@@ -27,24 +28,35 @@ import (
var validatorDepositDataValidatorAccount string
var validatorDepositDataWithdrawalAccount string
var validatorDepositDataDepositValue string
var validatorDepositDataRaw bool
var validatorDepositDataCmd = &cobra.Command{
Use: "depositdata",
Short: "Generate deposit data for a validator",
Long: `Generate data for a deposit to the Ethereum 1 validator contract. For example:
Short: "Generate deposit data for one or more validators",
Long: `Generate data for deposits to the Ethereum 1 validator contract. For example:
ethdo validator depositdata --validatoraccount=primary/validator --withdrawalaccount=primary/current --value="32 Ether"
In quiet mode this will return 0 if the the data can be generated correctly, otherwise 1.
If validatoraccount is provided with an account path it will generate deposit data for all matching accounts.
The information generated can be passed to ethereal to create a deposit from the Ethereum 1 chain.
In quiet mode this will return 0 if the the data can be generated correctly, otherwise 1.`,
Run: func(cmd *cobra.Command, args []string) {
assert(validatorDepositDataValidatorAccount != "", "--validatoraccount is required")
validatorAccount, err := accountFromPath(validatorDepositDataValidatorAccount)
validatorWallet, err := walletFromPath(validatorDepositDataValidatorAccount)
errCheck(err, "Failed to obtain validator wallet")
validatorAccounts, err := accountsFromPath(validatorDepositDataValidatorAccount)
errCheck(err, "Failed to obtain validator account")
outputIf(debug, fmt.Sprintf("Validator public key is %048x", validatorAccount.PublicKey().Marshal()))
assert(len(validatorAccounts) > 0, "Failed to obtain validator account")
if len(validatorAccounts) == 1 {
outputIf(debug, fmt.Sprintf("Validator public key is %048x", validatorAccounts[0].PublicKey().Marshal()))
} else {
for _, validatorAccount := range validatorAccounts {
outputIf(verbose, fmt.Sprintf("Creating deposit for %s/%s", validatorWallet.Name(), validatorAccount.Name()))
outputIf(debug, fmt.Sprintf("Validator public key is %048x", validatorAccount.PublicKey().Marshal()))
}
}
assert(validatorDepositDataWithdrawalAccount != "", "--withdrawalaccount is required")
withdrawalAccount, err := accountFromPath(validatorDepositDataWithdrawalAccount)
@@ -61,42 +73,84 @@ In quiet mode this will return 0 if the the data can be generated correctly, oth
errCheck(err, "Invalid value")
assert(val >= 1000000000, "deposit value must be at least 1 Ether")
depositData := struct {
PubKey []byte `ssz-size:"48"`
WithdrawalCredentials []byte `ssz-size:"32"`
Value uint64
}{
PubKey: validatorAccount.PublicKey().Marshal(),
WithdrawalCredentials: withdrawalCredentials,
Value: val,
}
signingRoot, err := ssz.HashTreeRoot(depositData)
errCheck(err, "Failed to generate deposit data signing root")
outputIf(debug, fmt.Sprintf("Signing root is %x", signingRoot))
domain := types.Domain(types.DomainDeposit, []byte{0, 0, 0, 0})
signature, err := sign(validatorDepositDataValidatorAccount, signingRoot[:], domain)
errCheck(err, "Failed to sign deposit data signing root")
// For each key, generate deposit data
outputs := make([]string, 0)
for _, validatorAccount := range validatorAccounts {
depositData := struct {
PubKey []byte `ssz-size:"48"`
WithdrawalCredentials []byte `ssz-size:"32"`
Value uint64
}{
PubKey: validatorAccount.PublicKey().Marshal(),
WithdrawalCredentials: withdrawalCredentials,
Value: val,
}
signingRoot, err := ssz.HashTreeRoot(depositData)
errCheck(err, "Failed to generate deposit data signing root")
outputIf(debug, fmt.Sprintf("Signing root is %x", signingRoot))
domain := types.Domain(types.DomainDeposit, []byte{0, 0, 0, 0})
err = validatorAccount.Unlock([]byte(rootAccountPassphrase))
errCheck(err, "Failed to unlock validator account")
signature, err := validatorAccount.Sign(signingRoot[:], domain)
validatorAccount.Lock()
errCheck(err, "Failed to sign deposit data signing root")
signedDepositData := struct {
PubKey []byte `ssz-size:"48"`
WithdrawalCredentials []byte `ssz-size:"32"`
Value uint64
Signature []byte `ssz-size:"96"`
}{
PubKey: validatorAccount.PublicKey().Marshal(),
WithdrawalCredentials: withdrawalCredentials,
Value: val,
Signature: signature.Marshal(),
signedDepositData := struct {
PubKey []byte `ssz-size:"48"`
WithdrawalCredentials []byte `ssz-size:"32"`
Value uint64
Signature []byte `ssz-size:"96"`
}{
PubKey: validatorAccount.PublicKey().Marshal(),
WithdrawalCredentials: withdrawalCredentials,
Value: val,
Signature: signature.Marshal(),
}
outputIf(debug, fmt.Sprintf("Deposit data signature is %x", signedDepositData.Signature))
depositDataRoot, err := ssz.HashTreeRoot(signedDepositData)
errCheck(err, "Failed to generate deposit data root")
outputIf(debug, fmt.Sprintf("Deposit data root is %x", depositDataRoot))
if validatorDepositDataRaw {
// Build a raw transaction by hand
txData := []byte{0x22, 0x89, 0x51, 0x18}
// Pointer to validator public key
txData = append(txData, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}...)
// Pointer to withdrawal credentials
txData = append(txData, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0}...)
// Pointer to validator signature
txData = append(txData, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20}...)
// Deposit data root
txData = append(txData, depositDataRoot[:]...)
// Validator public key (pad to 32-byte boundary)
txData = append(txData, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30}...)
txData = append(txData, validatorAccount.PublicKey().Marshal()...)
txData = append(txData, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}...)
// Withdrawal credentials
txData = append(txData, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20}...)
txData = append(txData, withdrawalCredentials...)
// Deposit signature
txData = append(txData, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60}...)
txData = append(txData, signedDepositData.Signature...)
outputs = append(outputs, fmt.Sprintf("%#x", txData))
} else {
outputs = append(outputs, fmt.Sprintf(`{"account":"%s","pubkey":"%048x","withdrawal_credentials":"%032x","signature":"%096x","value":%d,"deposit_data_root":"%032x"}`, fmt.Sprintf("%s/%s", validatorWallet.Name(), validatorAccount.Name()), signedDepositData.PubKey, signedDepositData.WithdrawalCredentials, signedDepositData.Signature, val, depositDataRoot))
}
}
outputIf(debug, fmt.Sprintf("Deposit data signature is %x", signedDepositData.Signature))
if quiet {
os.Exit(0)
}
depositDataRoot, err := ssz.HashTreeRoot(signedDepositData)
errCheck(err, "Failed to generate deposit data root")
outputIf(debug, fmt.Sprintf("Deposit data root is %x", depositDataRoot))
outputIf(!quiet, fmt.Sprintf(`{"pubkey":"%048x","withdrawal_credentials":"%032x","signature":"%096x","value":%d,"deposit_data_root":"%032x"}`, signedDepositData.PubKey, signedDepositData.WithdrawalCredentials, signedDepositData.Signature, val, depositDataRoot))
os.Exit(0)
if len(outputs) == 1 {
fmt.Printf("%s\n", outputs[0])
} else {
fmt.Printf("[")
fmt.Print(strings.Join(outputs, ","))
fmt.Println("]")
}
},
}
@@ -106,4 +160,5 @@ func init() {
validatorDepositDataCmd.Flags().StringVar(&validatorDepositDataValidatorAccount, "validatoraccount", "", "Account of the account carrying out the validation")
validatorDepositDataCmd.Flags().StringVar(&validatorDepositDataWithdrawalAccount, "withdrawalaccount", "", "Account of the account to which the validator funds will be withdrawn")
validatorDepositDataCmd.Flags().StringVar(&validatorDepositDataDepositValue, "depositvalue", "", "Value of the amount to be deposited")
validatorDepositDataCmd.Flags().BoolVar(&validatorDepositDataRaw, "raw", false, "Print raw deposit data transaction data")
}

114
cmd/validatorexit.go Normal file
View File

@@ -0,0 +1,114 @@
// Copyright © 2020 Weald Technology Trading
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"context"
"fmt"
"os"
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/wealdtech/ethdo/grpc"
types "github.com/wealdtech/go-eth2-types"
)
var validatorExitEpoch int64
var validatorExitCmd = &cobra.Command{
Use: "exit",
Short: "Send an exit request for a validator",
Long: `Send an exit request for a validator. For example:
ethdo validator exit --account=primary/validator --passphrase=secret
In quiet mode this will return 0 if the transaction has been sent, otherwise 1.`,
Run: func(cmd *cobra.Command, args []string) {
// Sanity checking and setup.
assert(rootAccount != "", "--account is required")
account, err := accountFromPath(rootAccount)
errCheck(err, "Failed to access account")
err = connect()
errCheck(err, "Failed to obtain connect to Ethereum 2 beacon chain node")
// Beacon chain config required for later work.
config, err := grpc.FetchChainConfig(eth2GRPCConn)
errCheck(err, "Failed to obtain beacon chain configuration")
// Fetch the validator's index.
index, err := grpc.FetchValidatorIndex(eth2GRPCConn, account)
errCheck(err, "Failed to obtain validator index")
outputIf(debug, fmt.Sprintf("Validator index is %d", index))
// Ensure the validator is active.
state, err := grpc.FetchValidatorState(eth2GRPCConn, account)
errCheck(err, "Failed to obtain validator state")
outputIf(debug, fmt.Sprintf("Validator state is %v", state))
assert(state == ethpb.ValidatorStatus_ACTIVE, "Validator must be active to exit")
// Ensure the validator has been active long enough to exit.
validator, err := grpc.FetchValidator(eth2GRPCConn, account)
errCheck(err, "Failed to obtain validator information")
outputIf(debug, fmt.Sprintf("Activation epoch is %v", validator.ActivationEpoch))
earliestExitEpoch := validator.ActivationEpoch + config["PersistentCommitteePeriod"].(uint64)
secondsPerEpoch := config["SecondsPerSlot"].(uint64) * config["SlotsPerEpoch"].(uint64)
genesisTime, err := grpc.FetchGenesis(eth2GRPCConn)
errCheck(err, "Failed to obtain genesis time")
currentEpoch := uint64(time.Since(genesisTime).Seconds()) / secondsPerEpoch
assert(currentEpoch >= earliestExitEpoch, fmt.Sprintf("Validator cannot exit until %s ( epoch %d)", genesisTime.Add(time.Duration(secondsPerEpoch*earliestExitEpoch)*time.Second).Format(time.Stamp), earliestExitEpoch))
outputIf(verbose, "Validator confirmed to be in a suitable state")
// Set up the transaction.
exit := &ethpb.VoluntaryExit{
Epoch: currentEpoch,
ValidatorIndex: index,
}
root, err := ssz.HashTreeRoot(exit)
errCheck(err, "Failed to generate exit proposal root")
// TODO fetch current fork version from config (currently using genesis fork version)
currentForkVersion := config["GenesisForkVersion"].([]byte)
domain := types.Domain(types.DomainVoluntaryExit, currentForkVersion)
err = account.Unlock([]byte(rootAccountPassphrase))
errCheck(err, "Failed to unlock account; please confirm passphrase is correct")
signature, err := sign(account, root[:], domain)
errCheck(err, "Failed to sign exit proposal")
proposal := &ethpb.SignedVoluntaryExit{
Exit: exit,
Signature: signature.Marshal(),
}
validatorClient := ethpb.NewBeaconNodeValidatorClient(eth2GRPCConn)
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
_, err = validatorClient.ProposeExit(ctx, proposal)
errCheck(err, "Failed to propose exit")
outputIf(!quiet, "Validator exit transaction sent")
os.Exit(_exit_success)
},
}
func init() {
validatorCmd.AddCommand(validatorExitCmd)
validatorFlags(validatorExitCmd)
validatorExitCmd.Flags().Int64Var(&validatorExitEpoch, "epoch", -1, "Epoch at which to exit (defaults to now)")
addTransactionFlags(validatorExitCmd)
}

View File

@@ -30,7 +30,7 @@ var versionCmd = &cobra.Command{
ethdo version.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("1.1.0")
fmt.Println("1.2.1")
if viper.GetBool("verbose") {
buildInfo, ok := dbg.ReadBuildInfo()
if ok {

View File

@@ -16,11 +16,8 @@ package cmd
import (
"fmt"
"os"
"sort"
"github.com/google/uuid"
"github.com/spf13/cobra"
types "github.com/wealdtech/go-eth2-types"
)
var walletAccountsCmd = &cobra.Command{
@@ -37,28 +34,21 @@ In quiet mode this will return 0 if the wallet holds any addresses, otherwise 1.
wallet, err := walletFromPath(walletWallet)
errCheck(err, "Failed to access wallet")
// List the accounts. They come to us in random order and we want them in name order, so store them in an array and sort
output := make([]addressListResult, 0)
hasAccounts := false
for account := range wallet.Accounts() {
output = append(output, addressListResult{id: account.ID(), name: account.Name(), pubkey: account.PublicKey()})
hasAccounts = true
if verbose {
fmt.Printf("%s\n\tUUID:\t\t%s\n\tPublic key:\t0x%048x\n", account.Name(), account.ID(), account.PublicKey().Marshal())
} else if !quiet {
fmt.Printf("%s\n", account.Name())
}
}
if quiet {
if len(output) == 0 {
os.Exit(1)
}
os.Exit(0)
}
sort.Slice(output, func(i, j int) bool {
return output[i].name < output[j].name
})
for _, out := range output {
if verbose {
fmt.Printf("%s\n\tUUID:\t\t%s\n\tPublic key:\t0x%048x\n", out.name, out.id, out.pubkey.Marshal())
} else if !quiet {
fmt.Printf("%s\n", out.name)
if hasAccounts {
os.Exit(_exit_success)
}
os.Exit(_exit_failure)
}
},
}
@@ -67,9 +57,3 @@ func init() {
walletCmd.AddCommand(walletAccountsCmd)
walletFlags(walletAccountsCmd)
}
type addressListResult struct {
id uuid.UUID
name string
pubkey types.PublicKey
}

View File

@@ -14,7 +14,10 @@
package cmd
import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/spf13/cobra"
"github.com/wealdtech/go-bytesutil"
@@ -36,6 +39,14 @@ In quiet mode this will return 0 if the wallet is imported successfully, otherwi
assert(walletImportData != "", "--walletimportdata is required")
assert(walletImportPassphrase != "", "--importpassphrase is required")
if !strings.HasPrefix(walletImportData, "0x") {
outputIf(debug, fmt.Sprintf("Reading wallet import from file %s", walletImportData))
// Assume this is a path
fileData, err := ioutil.ReadFile(walletImportData)
errCheck(err, "Failed to read wallet import data")
walletImportData = strings.TrimSpace(string(fileData))
}
outputIf(debug, fmt.Sprintf("Wallet import data is of length %d", len(walletImportData)))
importData, err := bytesutil.FromHexString(walletImportData)
errCheck(err, "Failed to decode wallet data")
@@ -49,6 +60,6 @@ In quiet mode this will return 0 if the wallet is imported successfully, otherwi
func init() {
walletCmd.AddCommand(walletImportCmd)
walletFlags(walletImportCmd)
walletImportCmd.Flags().StringVar(&walletImportData, "importdata", "", "The data to import")
walletImportCmd.Flags().StringVar(&walletImportData, "importdata", "", "The data to import, or the name of a file to read")
walletImportCmd.Flags().StringVar(&walletImportPassphrase, "importpassphrase", "", "Passphrase protecting the data to import")
}

View File

@@ -18,6 +18,7 @@ import (
"os"
"github.com/spf13/cobra"
wtypes "github.com/wealdtech/go-eth2-wallet-types"
)
var walletInfoCmd = &cobra.Command{
@@ -40,6 +41,15 @@ In quiet mode this will return 0 if the wallet exists, otherwise 1.`,
outputIf(verbose, fmt.Sprintf("UUID: %v", wallet.ID()))
fmt.Printf("Type: %s\n", wallet.Type())
if verbose {
if storeProvider, ok := wallet.(wtypes.StoreProvider); ok {
store := storeProvider.Store()
fmt.Printf("Store: %s\n", store.Name())
if storeLocationProvider, ok := store.(wtypes.StoreLocationProvider); ok {
fmt.Printf("Location: %s\n", storeLocationProvider.Location())
}
}
}
// Count the accounts.
accounts := 0

25
go.mod
View File

@@ -5,30 +5,37 @@ go 1.13
require (
github.com/FactomProject/go-bip39 v0.3.5
github.com/dgraph-io/ristretto v0.0.1 // indirect
github.com/google/uuid v1.1.1
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/golang/protobuf v1.3.3
github.com/grpc-ecosystem/grpc-gateway v1.12.2 // indirect
github.com/minio/highwayhash v1.0.0 // indirect
github.com/minio/sha256-simd v0.1.1 // indirect
github.com/mitchellh/go-homedir v1.1.0
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/pkg/errors v0.9.1
github.com/protolambda/zssz v0.1.4 // indirect
github.com/prysmaticlabs/ethereumapis v0.0.0-20200207140607-467d1b67d8d0
github.com/prysmaticlabs/go-bitfield v0.0.0-20191017011753-53b773adde52 // indirect
github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963
github.com/sirupsen/logrus v1.4.2
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v0.0.5
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.6.1
github.com/spf13/viper v1.6.2
github.com/wealdtech/go-bytesutil v1.1.0
github.com/wealdtech/go-eth2-types v1.0.0
github.com/wealdtech/go-eth2-util v1.1.0
github.com/wealdtech/go-eth2-wallet v1.8.0
github.com/wealdtech/go-eth2-wallet-types v1.8.0
github.com/wealdtech/go-eth2-wallet v1.8.1
github.com/wealdtech/go-eth2-wallet-hd v1.10.0 // indirect
github.com/wealdtech/go-eth2-wallet-nd v1.8.0 // indirect
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.7.0 // indirect
github.com/wealdtech/go-eth2-wallet-store-s3 v1.6.0 // indirect
github.com/wealdtech/go-eth2-wallet-types v1.10.0
github.com/wealdtech/go-string2eth v1.1.0
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect
golang.org/x/text v0.3.2 // indirect
gopkg.in/ini.v1 v1.51.1 // indirect
gopkg.in/yaml.v2 v2.2.7 // indirect
google.golang.org/genproto v0.0.0-20200207204624-4f3edf09f4f6 // indirect
google.golang.org/grpc v1.27.1
gopkg.in/ini.v1 v1.52.0 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)

142
go.sum
View File

@@ -7,20 +7,18 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/aws/aws-sdk-go v1.25.25 h1:j3HLOqcDWjNox1DyvJRs+kVQF42Ghtv6oL6cVBfXS3U=
github.com/aws/aws-sdk-go v1.25.25/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.25.33 h1:8muvpP+Bq5e0CDkM9PDZ6tN74fVUq5v3zSCRaZ93ykM=
github.com/aws/aws-sdk-go v1.25.33/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.25.50 h1:fTCp6qKnf1WLZGZtL0hh5PykCUaLZQBxlkTNG6fOK4I=
github.com/aws/aws-sdk-go v1.25.50/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.26.2 h1:MzYLmCeny4bMQcAbYcucIduVZKp0sEf1eRLvHpKI5Is=
github.com/aws/aws-sdk-go v1.26.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.28.0 h1:NkmnHFVEMTRYTleRLm5xUaL1mHKKkYQl4rCd+jzD58c=
github.com/aws/aws-sdk-go v1.28.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.28.1 h1:aWBD5EJrmGFuHFn9ZdaHqWWZGZYQ5Gzb3j9G0RppLpY=
github.com/aws/aws-sdk-go v1.28.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.28.13 h1:JyCQQ86yil3hg7MtWdNH8Pbcgx92qlUV2v22Km63Mf4=
github.com/aws/aws-sdk-go v1.28.13/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
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/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -41,6 +39,8 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczC
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dlespiau/covertool v0.0.0-20180314162135-b0c4c6d0583a/go.mod h1:/eQMcW3eA1bzKx23ZYI2H3tXPdJB5JWYTHzoUPBvQY4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -51,12 +51,18 @@ 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/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/pprof v0.0.0-20190309163659-77426154d546/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
@@ -66,7 +72,10 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.12.2 h1:D0EVSTwQoQOyfY35QNSuPJA4jpZRtkoGYWQMB7XNg5o=
github.com/grpc-ecosystem/grpc-gateway v1.12.2/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -81,8 +90,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -111,8 +118,6 @@ github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzI
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
github.com/phoreproject/bls v0.0.0-20190821133044-da95d4798b09 h1:f0WZnMl5hMHNpfUPR+klp00ZaIL1dLPZigpJUWupreI=
github.com/phoreproject/bls v0.0.0-20190821133044-da95d4798b09/go.mod h1:7pK0Ldy91shCmI47LLTn3i3rfTQcHiJJvPqGqzvN5nE=
github.com/phoreproject/bls v0.0.0-20191016230924-b2e57acce2ed h1:pX150rn565RorbtQWv2pR0SGd5rr9iHSGCSR26dg5Wk=
github.com/phoreproject/bls v0.0.0-20191016230924-b2e57acce2ed/go.mod h1:7pK0Ldy91shCmI47LLTn3i3rfTQcHiJJvPqGqzvN5nE=
github.com/phoreproject/bls v0.0.0-20191113194321-fef763a1a842 h1:SFS72hX189sQC+kZzAcNv7ENTLJHddmokEM39RsLA24=
github.com/phoreproject/bls v0.0.0-20191113194321-fef763a1a842/go.mod h1:xHJKf2TLXUA39Dhv8k5QmQOxLsbrb1KeTS/3ERfLeqc=
github.com/phoreproject/bls v0.0.0-20191211001008-9d5f85bf4a9b h1:tE/F54uL3jp0ZGSKNMPGCTF003pSmtD/sQojpKADAxY=
@@ -122,12 +127,15 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k=
github.com/pkg/errors v0.9.0/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
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/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -135,19 +143,18 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/protolambda/zssz v0.1.4 h1:4jkt8sqwhOVR8B1JebREU/gVX0Ply4GypsV8+RWrDuw=
github.com/protolambda/zssz v0.1.4/go.mod h1:a4iwOX5FE7/JkKA+J/PH0Mjo9oXftN6P8NZyL28gpag=
github.com/prysmaticlabs/ethereumapis v0.0.0-20200207140607-467d1b67d8d0 h1:kW97QgwiMpzsnQbFj9Y/jeGbD9gKtxKLktEzIqzkaNQ=
github.com/prysmaticlabs/ethereumapis v0.0.0-20200207140607-467d1b67d8d0/go.mod h1:5OkRN6UmvgtP+kIewitcEKC7S5KOzLOGtya/Tz+HBns=
github.com/prysmaticlabs/go-bitfield v0.0.0-20191017011753-53b773adde52 h1:kxZ+xSWX0qbxoiDXQBLztKeEmEQg6TgCYWAOa7gSGGU=
github.com/prysmaticlabs/go-bitfield v0.0.0-20191017011753-53b773adde52/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
github.com/prysmaticlabs/go-ssz v0.0.0-20191204195639-142dfef39d12 h1:bfPIvWvA7QSmIYARnHM9tgGx1LDeSKa2bYW5QGGArxQ=
github.com/prysmaticlabs/go-ssz v0.0.0-20191204195639-142dfef39d12/go.mod h1:VecIJZrewdAuhVckySLFt2wAAHRME934bSDurP8ftkc=
github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963 h1:Th5ufPIaL5s/7i3gXHTgiTwfsUhWDP/PwFRiI6qV6v0=
github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963/go.mod h1:VecIJZrewdAuhVckySLFt2wAAHRME934bSDurP8ftkc=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w=
github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
@@ -172,8 +179,8 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
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.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=
github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
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.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -191,55 +198,38 @@ github.com/wealdtech/go-bytesutil v1.0.1 h1:6xzMM+VEHf5WNh1PsIFcRwScgcno+CP8Rw1r
github.com/wealdtech/go-bytesutil v1.0.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s=
github.com/wealdtech/go-bytesutil v1.1.0 h1:6XrN7OIQhhBjQy/PZ1HZ3ySE8v8UDyxzERkOgmsIc1g=
github.com/wealdtech/go-bytesutil v1.1.0/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s=
github.com/wealdtech/go-ecodec v1.0.0 h1:QQj1t/yOGLsx8WUJaCTN+RrivgdWlP+r5ixzGzhlXVU=
github.com/wealdtech/go-ecodec v1.0.0/go.mod h1:PSdBFEB6cltdT7V4E1jbboufMZTZXcQOKG/2PeEjKK4=
github.com/wealdtech/go-ecodec v1.1.0 h1:yggrTSckcPJRaxxOxQF7FPm21kgE8WA6+f5jdq5Kr8o=
github.com/wealdtech/go-ecodec v1.1.0/go.mod h1:PSdBFEB6cltdT7V4E1jbboufMZTZXcQOKG/2PeEjKK4=
github.com/wealdtech/go-eth2-types v1.0.0 h1:ggrbQ5HeFcxVm20zxVWr8Sc3uCditaetzWB/Ax/4g0w=
github.com/wealdtech/go-eth2-types v1.0.0/go.mod h1:fWUgtKQ7hiNVl6263bGeyjlydYuaxkxcUIPIopgz2CM=
github.com/wealdtech/go-eth2-util v1.0.0 h1:sKnZ84xLzj1PntxaWeiGmA+1LZ6vOeIXqCHDkVvzRGU=
github.com/wealdtech/go-eth2-util v1.0.0/go.mod h1:ZodZI58Seya6uhbMLe3cLydsV0AhneyWCHzmkJCKlIM=
github.com/wealdtech/go-eth2-util v1.1.0 h1:bDgNEtH5LoxI1JaBPUgHoPKmfPwtGuLw487U7AoMO6E=
github.com/wealdtech/go-eth2-util v1.1.0/go.mod h1:mX11133nOroRPHp3qXyAqT5iLmsZXQmpH2DZWWeFWP8=
github.com/wealdtech/go-eth2-wallet v1.5.0 h1:6QFNfXyX009C8WIxnflyEctogx1QzQ8cBb7Vftyp5VE=
github.com/wealdtech/go-eth2-wallet v1.5.0/go.mod h1:jpYP8snFvI3/rTS+zdfyyUsyf6EXoSHl5ByWmFYq72Q=
github.com/wealdtech/go-eth2-wallet v1.8.0 h1:QO8HzHDXNgc8AEBulz0IFdk+U9SDc0+UX3dNVstB8wY=
github.com/wealdtech/go-eth2-wallet v1.8.0/go.mod h1:PWvCjr8NXZbEIIpFYAc7tgjc50X9PCo7K4LzXn3//bY=
github.com/wealdtech/go-eth2-wallet v1.8.1 h1:w5fD2c0Q9WSYbTF7XpdBsiTcPUHfLlU1blAhH8ROffY=
github.com/wealdtech/go-eth2-wallet v1.8.1/go.mod h1:Kvzo9EdxUvibt/KarimGTOHY3pEcQTyIV1A+XDmei48=
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.0.0 h1:IcpS4VpXhYz+TVupB5n6C6IQzaKwG+Rc8nvgCa/da4c=
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.0.0/go.mod h1:X8WRO5hEwbjx8ZOqoRmtS1ngyflKs25GkP7qGv7yOqE=
github.com/wealdtech/go-eth2-wallet-hd v1.6.0 h1:01G1IzKmpO33+jUEmdAU5My/PmoKjSoxsli9LpXQl9w=
github.com/wealdtech/go-eth2-wallet-hd v1.6.0/go.mod h1:Fmr23uSPnsPp9kDV7A3W816qzxU15QS0cq4qm2Cbc+I=
github.com/wealdtech/go-eth2-wallet-hd v1.7.0 h1:q4YyUOAkbRPK84uBFPVg+jVuLCo1VVh7KE8ZgIW6aUU=
github.com/wealdtech/go-eth2-wallet-hd v1.7.0/go.mod h1:sDiIKeBg8zz1lBVJYdks8my4Qj/+Q5j4mZ8OcyA1mCM=
github.com/wealdtech/go-eth2-wallet-hd v1.8.0 h1:3oYkM6H94vA5y5RUtiBErrZSOxZnwgqRC2Yg6ZnABVg=
github.com/wealdtech/go-eth2-wallet-hd v1.8.0/go.mod h1:EgleYFBLF2AFAPkoNiEsVJkfRMjOj76zKtKEx38bjuk=
github.com/wealdtech/go-eth2-wallet-hd v1.9.0 h1:AtBkFvE4Usrzz+jkLgThfSW5kiXKKbQLK8rHS9OXu5I=
github.com/wealdtech/go-eth2-wallet-hd v1.9.0/go.mod h1:QGIkXF1AtI9cLByFlnnRXDoK01/SuunRfGLzhWDMnCU=
github.com/wealdtech/go-eth2-wallet-nd v1.5.0 h1:0nOOD0TpvGTSbRF7NGxAzgFPoEdM0Awnr9Mx3mroOm4=
github.com/wealdtech/go-eth2-wallet-nd v1.5.0/go.mod h1:KiORm3eoIq+XR043MPekEPebU8I12918bE7ldrqk9iw=
github.com/wealdtech/go-eth2-wallet-nd v1.6.0 h1:uMX6K/LdJdo56vaR8pIDrwGDX8w+e/MxA88B19Ys/gw=
github.com/wealdtech/go-eth2-wallet-nd v1.6.0/go.mod h1:oVsPJTBSHnBphYush38VQYCuLwYi/HViqvZByh9vqJ0=
github.com/wealdtech/go-eth2-wallet-nd v1.7.0 h1:hdQ1XTbz/d1ySY5/kDNQokVP7nM3i6pe/tLgVJqhlxk=
github.com/wealdtech/go-eth2-wallet-nd v1.7.0/go.mod h1:3vaCTMI2yPndhgjXqM6ynv3yrU0VvqksQ4MaQLCgZIo=
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.4.0 h1:IH9ncOXxd10A4C6EAptnycuRcoenRmf60oKq5yirfpc=
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.4.0/go.mod h1:FCzZpqn1KqU1ezKKjjxh6l9NjmCAiTwZksgE+bnTD68=
github.com/wealdtech/go-eth2-wallet-hd v1.9.1 h1:u53yvtm4cJM3HZS0L9Lt1i3YjbxJ9y4SJvlcsp2nX6o=
github.com/wealdtech/go-eth2-wallet-hd v1.9.1/go.mod h1:QGIkXF1AtI9cLByFlnnRXDoK01/SuunRfGLzhWDMnCU=
github.com/wealdtech/go-eth2-wallet-hd v1.10.0 h1:rWpJRWXrnLGLadSOIhCqxAkSIOd93knxxUVxvScV/qw=
github.com/wealdtech/go-eth2-wallet-hd v1.10.0/go.mod h1:LiuHHIG7pU/u598yZBqsjWk0p5LmclxdPQeUSKJJwkg=
github.com/wealdtech/go-eth2-wallet-nd v1.7.1 h1:UtOUJaaVDYybYAZInCnKqVbiHEoqLzg6XlVs1qMoNgo=
github.com/wealdtech/go-eth2-wallet-nd v1.7.1/go.mod h1:3vaCTMI2yPndhgjXqM6ynv3yrU0VvqksQ4MaQLCgZIo=
github.com/wealdtech/go-eth2-wallet-nd v1.8.0 h1:DD7QRS3mPS6GH0vNFn2DcJ3mHRgc+gtQ0Uq189pWZ00=
github.com/wealdtech/go-eth2-wallet-nd v1.8.0/go.mod h1:o0nR55vuaKZ4d+FuzzDhapu0LBQvk5CUER7ZCg1IYH8=
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.5.0 h1:bVOahxWdk0qkZ6xseQBw8fNmCDIbmIM/4KHY+cUSWj8=
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.5.0/go.mod h1:8zwb4tAWxGF4PZCNNYdkjlGQYbTEadkKwCkSNyCOfm4=
github.com/wealdtech/go-eth2-wallet-store-s3 v1.3.0 h1:Cl/XoJUwUPPO1pq8PpFg+UWSO4XyJC5h+kKYBpgQtMM=
github.com/wealdtech/go-eth2-wallet-store-s3 v1.3.0/go.mod h1:bW+mIEvCitsc3+ZYIIzaawCjrCtI+CpGUAIrevesOSw=
github.com/wealdtech/go-eth2-wallet-store-s3 v1.4.0 h1:7M5pJeMUhTTAjKFNd7//clwV5c8IDbbmBQJiMOPmFu8=
github.com/wealdtech/go-eth2-wallet-store-s3 v1.4.0/go.mod h1:XDUlPyp6q2X53yIktwP4gRXk6JLbegr4dp67GBgO5T0=
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.7.0 h1:SJ1yx0K9bk/W7M7lSiOVIm2Trs0FTlQ3wkAfOIl82qk=
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.7.0/go.mod h1:XM1bKpfV6dPdygA1HMO7vx1Vxlir8VMa649mcD2uudg=
github.com/wealdtech/go-eth2-wallet-store-s3 v1.5.0 h1:ZbG99FcnBJrZhVWIfcWS/qe4C8dcog0Amjj6v+RraSE=
github.com/wealdtech/go-eth2-wallet-store-s3 v1.5.0/go.mod h1:NTchwZDLDZhrzF3ENkC890m4SKt5SI8mHdn5XJryVL0=
github.com/wealdtech/go-eth2-wallet-store-scratch v1.2.0 h1:GzwNLhfHlR25PXSNWPFBQwMA4nQS80WLTp9DWKhUDXU=
github.com/wealdtech/go-eth2-wallet-store-scratch v1.2.0/go.mod h1:Rmi0S69tuts1YbVXcimw/4yvYUSiLNIUE9gIT3i1h4E=
github.com/wealdtech/go-eth2-wallet-store-s3 v1.6.0 h1:Xuq7JJ1DE8eGY6n3E/a+lgyySB7mvudAFaNbdEo+Srk=
github.com/wealdtech/go-eth2-wallet-store-s3 v1.6.0/go.mod h1:OjE3G9zCPgJs/W4EVpvIIg+d8X/I8uA1bR9ZVBwf22M=
github.com/wealdtech/go-eth2-wallet-store-scratch v1.3.0 h1:iC0pZQY9zfh1onYHwnkiQa6V998LVK54U5ShUu7QTf8=
github.com/wealdtech/go-eth2-wallet-store-scratch v1.3.0/go.mod h1:NaV/et5zTaqHhTpdpSveUYE2czCFAD8f07eABh/0pso=
github.com/wealdtech/go-eth2-wallet-types v1.5.0 h1:9uRdSws4Wg42lQ63AEg4X/1Mt/si5MIZOBaVpuCyrLU=
github.com/wealdtech/go-eth2-wallet-types v1.5.0/go.mod h1:OQqqr/hWOwNHe9NyXI0cYGQI6CBBmAlcusqWnJCf7T8=
github.com/wealdtech/go-eth2-wallet-types v1.7.0 h1:wzIrTpD31rFWJIU2rWGOowoaDBpl7nTSHL8W0tjv2oo=
github.com/wealdtech/go-eth2-wallet-types v1.7.0/go.mod h1:5A83MUBhmLgxpg9X5eqvnDIOYfn329caf5DOcv7pcY0=
github.com/wealdtech/go-eth2-wallet-types v1.8.0 h1:6K/u5CTcUavgzoABeeuBAZ0jp1qEOdK/9U8gaMJUlVE=
github.com/wealdtech/go-eth2-wallet-types v1.8.0/go.mod h1:5A83MUBhmLgxpg9X5eqvnDIOYfn329caf5DOcv7pcY0=
github.com/wealdtech/go-eth2-wallet-types v1.10.0 h1:iQx3MxMQQwoEfyPDHy5vtKYVtrUjY4nzEODbUPcz2bg=
github.com/wealdtech/go-eth2-wallet-types v1.10.0/go.mod h1:vwK05jlJM/ibZs/QCqJ4dOhsjjpNcIP4X7Vx6WYXLGI=
github.com/wealdtech/go-indexer v1.0.0 h1:/S4rfWQbSOnnYmwnvuTVatDibZ8o1s9bmTCHO16XINg=
github.com/wealdtech/go-indexer v1.0.0/go.mod h1:u1cjsbsOXsm5jzJDyLmZY7GsrdX8KYXKBXkZcAmk3Zg=
github.com/wealdtech/go-string2eth v1.1.0 h1:USJQmysUrBYYmZs7d45pMb90hRSyEwizP7lZaOZLDAw=
@@ -260,31 +250,35 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRi
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59 h1:PyXRxSVbvzDGuqYXjHndV7xDzJ7w2K8KD9Ef8GB7KOE=
golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191111213947-16651526fdb4 h1:AGVXd+IAyeAb3FuQvYDYQ9+WR2JHm0+C0oYJaU1C4rs=
golang.org/x/crypto v0.0.0-20191111213947-16651526fdb4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708 h1:pXVtWnwHkrWD9ru3sDxY/qFK/bfc0egRovX91EjWjf4=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 h1:nVJ3guKA9qdkEQ3TUdXI9QSINo2CUPM/cySEvw2w8I0=
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200208060501-ecb85df21340 h1:KOcEaR10tFr7gdJV2GCKw8Os5yED1u1aOqHjOAb6d2Y=
golang.org/x/crypto v0.0.0-20200208060501-ecb85df21340/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190326090315-15845e8f865b/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -294,17 +288,14 @@ golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4 h1:Hynbrlo6LbYI3H1IqXpkVDOcX/3HiPdhVEuyj5a59RM=
golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea h1:Mz1TMnfJDRJLk8S8OPCoJYgrsp/Se/2TBre2+vwX128=
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/jk7KtquiArPoeX0WvA=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -313,13 +304,28 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190106171756-3ef68632349c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190325223049-1d95b17f1b04/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20200207204624-4f3edf09f4f6 h1:tirixpud1WdjE3/NrL9ar4ot0ADfwls8sOcIf1ivRDw=
google.golang.org/genproto v0.0.0-20200207204624-4f3edf09f4f6/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -327,15 +333,17 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1 h1:GyboHr4UqMiLUybYjd22ZjQIKEJEpgtLXtuGbR21Oho=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.52.0 h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4=
gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
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.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

87
grpc/beaconchain.go Normal file
View File

@@ -0,0 +1,87 @@
// Copyright © 2020 Weald Technology Trading
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grpc
import (
"context"
"strconv"
"strings"
"github.com/pkg/errors"
"github.com/spf13/viper"
"google.golang.org/grpc"
"github.com/golang/protobuf/ptypes/empty"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
wtypes "github.com/wealdtech/go-eth2-wallet-types"
)
// FetchChainConfig fetches the chain configuration from the beacon node.
// It tweaks the output to make it easier to work with by setting appropriate
// types.
func FetchChainConfig(conn *grpc.ClientConn) (map[string]interface{}, error) {
beaconClient := ethpb.NewBeaconChainClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
config, err := beaconClient.GetBeaconConfig(ctx, &empty.Empty{})
if err != nil {
return nil, err
}
results := make(map[string]interface{})
for k, v := range config.Config {
// Handle integers
if v == "0" {
results[k] = uint64(0)
continue
}
intVal, err := strconv.ParseUint(v, 10, 64)
if err == nil && intVal != 0 {
results[k] = intVal
continue
}
// Handle byte arrays
if strings.HasPrefix(v, "[") {
vals := strings.Split(v[1:len(v)-1], " ")
res := make([]byte, len(vals))
for i, val := range vals {
intVal, err := strconv.Atoi(val)
if err != nil {
return nil, errors.Wrapf(err, "failed to convert value %q for %s", v, k)
}
res[i] = byte(intVal)
}
results[k] = res
continue
}
// String (or unhandled format)
results[k] = v
}
return results, nil
}
// FetchValidator fetches validator information from the beacon node.
func FetchValidator(conn *grpc.ClientConn, account wtypes.Account) (*ethpb.Validator, error) {
beaconClient := ethpb.NewBeaconChainClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
req := &ethpb.GetValidatorRequest{
QueryFilter: &ethpb.GetValidatorRequest_PublicKey{
PublicKey: account.PublicKey().Marshal(),
},
}
return beaconClient.GetValidator(ctx, req)
}

60
grpc/beaconnode.go Normal file
View File

@@ -0,0 +1,60 @@
// Copyright © 2020 Weald Technology Trading
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grpc
import (
"context"
"github.com/spf13/viper"
"google.golang.org/grpc"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
wtypes "github.com/wealdtech/go-eth2-wallet-types"
)
// FetchValidatorIndex fetches the index of a validator.
func FetchValidatorIndex(conn *grpc.ClientConn, account wtypes.Account) (uint64, error) {
validatorClient := ethpb.NewBeaconNodeValidatorClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
// Fetch the account.
req := &ethpb.ValidatorIndexRequest{
PublicKey: account.PublicKey().Marshal(),
}
resp, err := validatorClient.ValidatorIndex(ctx, req)
if err != nil {
return 0, err
}
return resp.Index, nil
}
// FetchValidatorState fetches the state of a validator.
func FetchValidatorState(conn *grpc.ClientConn, account wtypes.Account) (ethpb.ValidatorStatus, error) {
validatorClient := ethpb.NewBeaconNodeValidatorClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
// Fetch the account.
req := &ethpb.ValidatorStatusRequest{
PublicKey: account.PublicKey().Marshal(),
}
resp, err := validatorClient.ValidatorStatus(ctx, req)
if err != nil {
return 0, err
}
return resp.Status, nil
}

37
grpc/node.go Normal file
View File

@@ -0,0 +1,37 @@
// Copyright © 2020 Weald Technology Trading
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grpc
import (
"context"
"time"
"github.com/spf13/viper"
"google.golang.org/grpc"
"github.com/golang/protobuf/ptypes/empty"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
)
// FetchGenesis fetches the genesis time.
func FetchGenesis(conn *grpc.ClientConn) (time.Time, error) {
client := ethpb.NewNodeClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
res, err := client.GetGenesis(ctx, &empty.Empty{})
if err != nil {
return time.Now(), err
}
return time.Unix(res.GetGenesisTime().Seconds, 0), nil
}