├── codec ├── test │ ├── empty.pem │ ├── corrupt.pem │ ├── valid.pem │ └── alternate.pem ├── types.go ├── util.go ├── decode_test.go ├── decode.go └── encode.go ├── e2e ├── powershell │ └── test.ps1 └── bash │ ├── util │ ├── _.bash │ └── assert.bash │ └── test.bats ├── util ├── newline_linux.go ├── newline_darwin.go └── newline_windows.go ├── .github ├── CODEOWNERS └── workflows │ ├── install │ ├── linux │ │ ├── bats-core.sh │ │ ├── bats-support.sh │ │ └── go.sh │ ├── darwin │ │ ├── bats-core.sh │ │ ├── bats-support.sh │ │ └── go.sh │ └── windows │ │ └── go.ps1 │ └── ci.yaml ├── .gitignore ├── public.key ├── keysmith-completions.bash ├── cmd ├── version.go ├── shortlist.go ├── util.go ├── generate.go ├── x-public-key.go ├── x-private-key.go ├── public-key.go ├── account.go ├── principal.go ├── legacy-address.go └── private-key.go ├── go.mod ├── seed └── seed.go ├── account └── account.go ├── usage.go ├── CHANGELOG.md ├── LICENSE ├── quill_migration.md ├── principal ├── principal_test.go └── principal.go ├── crypto └── crypto.go ├── main.go ├── Makefile ├── README.md └── go.sum /codec/test/empty.pem: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /e2e/powershell/test.ps1: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /codec/test/corrupt.pem: -------------------------------------------------------------------------------- 1 | Hello World 2 | -------------------------------------------------------------------------------- /util/newline_linux.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | const NewLine = "\n" 4 | -------------------------------------------------------------------------------- /util/newline_darwin.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | const NewLine = "\n" 4 | -------------------------------------------------------------------------------- /util/newline_windows.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | const NewLine = "\r\n" 4 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # The whole SDK team owns the whole repo for now. 2 | * @dfinity/dx -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | identity.bip32 2 | identity.pem 3 | keysmith 4 | keysmith.exe 5 | release/ 6 | seed.txt 7 | -------------------------------------------------------------------------------- /e2e/bash/util/_.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | keysmith="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd -P)/../../../keysmith" 4 | -------------------------------------------------------------------------------- /.github/workflows/install/linux/bats-core.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | # Install Bats Core. 5 | sudo apt-get install -y bats 6 | -------------------------------------------------------------------------------- /.github/workflows/install/darwin/bats-core.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | # Install Bats Core. 5 | brew unlink bats || : 6 | brew install bats-core 7 | -------------------------------------------------------------------------------- /public.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE5GYgJjmwEwqNOFlWnsGVnNFuCshNGOY+ 3 | 0WDnt598B8gyban7Oml+A3KkzC1PEKY+GEOB/G2SLzMLcUbj9NDtvQ== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /keysmith-completions.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | _keysmith_completions() 4 | { 5 | if [ "${#COMP_WORDS[@]}" != "2" ]; then 6 | return 7 | fi 8 | COMPREPLY=($(compgen -W "$(keysmith shortlist)" "${COMP_WORDS[1]}")) 9 | } 10 | 11 | complete -F _keysmith_completions keysmith 12 | -------------------------------------------------------------------------------- /codec/test/valid.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BgUrgQQACg== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHQCAQEEIGaIXBMXDISfmzTyCFZYdpK5xffF3VCdiq2hTMQfigUFoAcGBSuBBAAK 6 | oUQDQgAEVy3tMmR2YP4u8sx0I4oviblc9rIU45qQ2q+qwSqdOTXp4F6w1/zCSgHD 7 | q2/nqGNhamHErbu0gukKgest1aK0bA== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /codec/test/alternate.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEIC0IfcinOY9BTdSm944ur94wGaex0hyOBpxqdK1Ewx3NoAoGCCqGSM49 6 | AwEHoUQDQgAE/6gIH6DEYs7e4s8sTwfAaKcU6cmKiReRuu6xX2hdp3x04Am/HTfr 7 | /QRs8VPKanRl8RgisBMYkAbk3wsCTXwY6A== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const VERSION_CMD = "version" 8 | 9 | type VersionCmd struct { 10 | Version string 11 | } 12 | 13 | func NewVersionCmd(version string) *VersionCmd { 14 | return &VersionCmd{Version: version} 15 | } 16 | 17 | func (cmd *VersionCmd) Run() error { 18 | fmt.Println(cmd.Version) 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /codec/types.go: -------------------------------------------------------------------------------- 1 | package codec 2 | 3 | import ( 4 | "encoding/asn1" 5 | ) 6 | 7 | type ECPrivKey struct { 8 | Version int 9 | PrivateKey []byte 10 | NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` 11 | PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` 12 | } 13 | 14 | type ECPubKey struct { 15 | Metadata []asn1.ObjectIdentifier 16 | PublicKey asn1.BitString 17 | } 18 | -------------------------------------------------------------------------------- /codec/util.go: -------------------------------------------------------------------------------- 1 | package codec 2 | 3 | import ( 4 | "encoding/asn1" 5 | ) 6 | 7 | func Secp256k1() asn1.ObjectIdentifier { 8 | return asn1.ObjectIdentifier{1, 3, 132, 0, 10} 9 | } 10 | 11 | func IsSecp256k1(actual asn1.ObjectIdentifier) bool { 12 | expect := Secp256k1() 13 | if len(expect) != len(actual) { 14 | return false 15 | } 16 | for i := range actual { 17 | if expect[i] != actual[i] { 18 | return false 19 | } 20 | } 21 | return true 22 | } 23 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/dfinity/keysmith 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/btcsuite/btcd v0.21.0-beta 7 | github.com/btcsuite/btcutil v1.0.2 // indirect 8 | github.com/dfinity/go-hdkeychain v1.1.0 9 | github.com/ethereum/go-ethereum v1.10.12 10 | github.com/tyler-smith/go-bip39 v1.1.0 11 | golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d 12 | ) 13 | 14 | replace ( 15 | github.com/tyler-smith/go-bip39 => github.com/tyler-smith/go-bip39 v1.1.0 16 | ) 17 | -------------------------------------------------------------------------------- /.github/workflows/install/darwin/bats-support.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | # Define version and tarball. 5 | VERSION="0.3.0" 6 | TARBALL="v${VERSION}.tar.gz" 7 | 8 | # Install Bats Support. 9 | pushd /tmp 10 | curl -L -O -s "https://github.com/ztombol/bats-support/archive/${TARBALL}" 11 | pushd /usr/local/lib 12 | tar -f /tmp/${TARBALL} -x 13 | ln -s bats-support-${VERSION} bats-support 14 | popd 15 | popd 16 | 17 | # Configure workspace. 18 | BATS_SUPPORT="/usr/local/lib/bats-support" 19 | echo "BATS_SUPPORT=${BATS_SUPPORT}" >> ${GITHUB_ENV} 20 | -------------------------------------------------------------------------------- /.github/workflows/install/linux/bats-support.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | # Define version and tarball. 5 | VERSION="0.3.0" 6 | TARBALL="v${VERSION}.tar.gz" 7 | 8 | # Install Bats Support. 9 | pushd /tmp 10 | wget -q "https://github.com/ztombol/bats-support/archive/${TARBALL}" 11 | pushd /usr/local/lib 12 | sudo tar -f /tmp/${TARBALL} -x 13 | sudo ln -s bats-support-${VERSION} bats-support 14 | popd 15 | popd 16 | 17 | # Configure workspace. 18 | BATS_SUPPORT="/usr/local/lib/bats-support" 19 | echo "BATS_SUPPORT=${BATS_SUPPORT}" >> ${GITHUB_ENV} 20 | -------------------------------------------------------------------------------- /cmd/shortlist.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | const SHORTLIST_CMD = "shortlist" 9 | 10 | type ShortlistCmd struct { 11 | } 12 | 13 | func NewShortlistCmd() *ShortlistCmd { 14 | return &ShortlistCmd{} 15 | } 16 | 17 | func (cmd *ShortlistCmd) Run() error { 18 | output := strings.Join([]string{ 19 | ACCOUNT_CMD, 20 | GENERATE_CMD, 21 | LEGACY_ADDRESS_CMD, 22 | PRINCIPAL_CMD, 23 | PRIVATE_KEY_CMD, 24 | PUBLIC_KEY_CMD, 25 | SHORTLIST_CMD, 26 | VERSION_CMD, 27 | X_PRIVATE_KEY_CMD, 28 | X_PUBLIC_KEY_CMD, 29 | }, " ") 30 | fmt.Println(output) 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /cmd/util.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "io/fs" 6 | "os" 7 | ) 8 | 9 | func writeFileOrStdout(file string, output []byte, perm fs.FileMode) error { 10 | if file == "-" { 11 | fmt.Print(string(output)) 12 | return nil 13 | } else { 14 | handle, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm) 15 | if err != nil { 16 | return fmt.Errorf("Output file already exists: %s", file) 17 | } 18 | defer handle.Close() 19 | n, err := handle.Write(output) 20 | if err != nil || n != len(output) { 21 | return fmt.Errorf("Cannot write output to file: %s", file) 22 | } 23 | return nil 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /codec/decode_test.go: -------------------------------------------------------------------------------- 1 | package codec 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestLoadAlternate(test *testing.T) { 8 | _, err := LoadECPrivKey("test/alternate.pem") 9 | if err == nil { 10 | test.Fatal("Failed to reject alternate identity file.") 11 | } 12 | } 13 | 14 | func TestLoadCorrupt(test *testing.T) { 15 | _, err := LoadECPrivKey("test/corrupt.pem") 16 | if err == nil { 17 | test.Fatal("Failed to reject corrupt identity file.") 18 | } 19 | } 20 | 21 | func TestLoadEmpty(test *testing.T) { 22 | _, err := LoadECPrivKey("test/empty.pem") 23 | if err == nil { 24 | test.Fatal("Failed to reject empty identity file.") 25 | } 26 | } 27 | 28 | func TestLoadValid(test *testing.T) { 29 | _, err := LoadECPrivKey("test/valid.pem") 30 | if err != nil { 31 | test.Fatal("Failed to accept valid identity file.") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/install/linux/go.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | # Define operating system and architecture. 5 | GOOS=linux 6 | case "$(uname -m)" in 7 | x86_64) 8 | GOARCH="amd64";; 9 | arm64) 10 | GOARCH="arm64";; 11 | *) 12 | echo "Error: Unsupported architecture!" 13 | exit 1 14 | esac 15 | 16 | # Define version and tarball. 17 | VERSION="1.16" 18 | TARBALL="go${VERSION}.${GOOS}-${GOARCH}.tar.gz" 19 | 20 | # Install Go compiler. 21 | pushd /tmp 22 | wget -q "https://storage.googleapis.com/golang/${TARBALL}" 23 | pushd /usr/local 24 | sudo tar -f /tmp/${TARBALL} -x 25 | popd 26 | popd 27 | 28 | # Configure workspace. 29 | GOROOT="/usr/local/go" 30 | GOPATH="${HOME}/go" 31 | echo "GOOS=${GOOS}" >> ${GITHUB_ENV} 32 | echo "GOARCH=${GOARCH}" >> ${GITHUB_ENV} 33 | echo "GOROOT=${GOROOT}" >> ${GITHUB_ENV} 34 | echo "GOPATH=${GOPATH}" >> ${GITHUB_ENV} 35 | echo "${GOROOT}/bin" >> ${GITHUB_PATH} 36 | echo "${GOPATH}/bin" >> ${GITHUB_PATH} 37 | mkdir ${GOPATH} 38 | -------------------------------------------------------------------------------- /.github/workflows/install/darwin/go.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | # Define operating system and architecture. 5 | GOOS=darwin 6 | case "$(uname -m)" in 7 | x86_64) 8 | GOARCH="amd64";; 9 | arm64) 10 | GOARCH="arm64";; 11 | *) 12 | echo "Error: Unsupported architecture!" 13 | exit 1 14 | esac 15 | 16 | # Define version and tarball. 17 | VERSION="1.16" 18 | TARBALL="go${VERSION}.${GOOS}-${GOARCH}.tar.gz" 19 | 20 | # Install Go compiler. 21 | pushd /tmp 22 | curl -L -O -s "https://storage.googleapis.com/golang/${TARBALL}" 23 | pushd /usr/local 24 | sudo tar -f /tmp/${TARBALL} -x 25 | popd 26 | popd 27 | 28 | # Configure workspace. 29 | GOROOT="/usr/local/go" 30 | GOPATH="${HOME}/go" 31 | echo "GOOS=${GOOS}" >> ${GITHUB_ENV} 32 | echo "GOARCH=${GOARCH}" >> ${GITHUB_ENV} 33 | echo "GOROOT=${GOROOT}" >> ${GITHUB_ENV} 34 | echo "GOPATH=${GOPATH}" >> ${GITHUB_ENV} 35 | echo "${GOROOT}/bin" >> ${GITHUB_PATH} 36 | echo "${GOPATH}/bin" >> ${GITHUB_PATH} 37 | mkdir ${GOPATH} 38 | -------------------------------------------------------------------------------- /seed/seed.go: -------------------------------------------------------------------------------- 1 | package seed 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | 9 | "github.com/tyler-smith/go-bip39" 10 | "golang.org/x/term" 11 | ) 12 | 13 | func Load(seedFile string, protected bool) ([]byte, error) { 14 | mnemonic, err := readFileOrStdin(seedFile) 15 | if err != nil { 16 | return nil, err 17 | } 18 | var password []byte 19 | if protected { 20 | fmt.Printf("Password: ") 21 | password, err = term.ReadPassword(int(os.Stdin.Fd())) 22 | fmt.Println("") 23 | if err != nil { 24 | return nil, err 25 | } 26 | } 27 | mnemonic = bytes.Join(bytes.Fields(mnemonic), []byte(" ")) 28 | return bip39.NewSeedWithErrorChecking( 29 | string(mnemonic), 30 | string(password), 31 | ) 32 | } 33 | 34 | func readFileOrStdin(file string) ([]byte, error) { 35 | reader := os.Stdin 36 | var err error 37 | if file != "-" { 38 | reader, err = os.Open(file) 39 | if err != nil { 40 | return nil, err 41 | } 42 | defer reader.Close() 43 | } 44 | return ioutil.ReadAll(reader) 45 | } 46 | -------------------------------------------------------------------------------- /account/account.go: -------------------------------------------------------------------------------- 1 | package account 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/binary" 6 | "encoding/hex" 7 | "hash/crc32" 8 | 9 | "github.com/btcsuite/btcd/btcec" 10 | "github.com/dfinity/keysmith/codec" 11 | "github.com/dfinity/keysmith/principal" 12 | ) 13 | 14 | type AccountId interface { 15 | String() string 16 | } 17 | 18 | type accountId struct { 19 | data []byte 20 | } 21 | 22 | func FromECPubKey(pubKey *btcec.PublicKey) (AccountId, error) { 23 | der, err := codec.EncodeECPubKey(pubKey) 24 | if err != nil { 25 | return nil, err 26 | } 27 | hash := sha256.New224() 28 | hash.Write([]byte("\x0Aaccount-id")) 29 | hash.Write(principal.NewSelfAuthenticatingId(der).Bytes()) 30 | hash.Write(make([]byte, 32)) 31 | data := hash.Sum(nil) 32 | return &accountId{data: data}, nil 33 | } 34 | 35 | func (accountId *accountId) String() string { 36 | crc := make([]byte, 4) 37 | binary.BigEndian.PutUint32(crc, crc32.ChecksumIEEE(accountId.data)) 38 | return hex.EncodeToString(append(crc, accountId.data...)) 39 | } 40 | -------------------------------------------------------------------------------- /.github/workflows/install/windows/go.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | $ErrorActionPreference="Stop" 3 | Set-PSDebug -Trace 1 4 | 5 | # Define operating system and architecture. 6 | $goos="windows" 7 | $goarch="amd64" 8 | 9 | # Define version and zip file. 10 | $version="1.16" 11 | $zipfile="go$version.$goos-$goarch.zip" 12 | 13 | # Install Go compiler. 14 | Push-Location $env:TEMP 15 | $client=new-object System.Net.WebClient 16 | $client.DownloadFile("https://storage.googleapis.com/golang/$zipfile", $zipfile) 17 | Add-Type -AssemblyName System.IO.Compression.FileSystem 18 | [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, "C:\") 19 | Pop-Location 20 | 21 | # Configure workspace. 22 | $goroot="C:\go" 23 | $gopath="$home\go" 24 | echo "GOOS=$goos" >> $env:GITHUB_ENV 25 | echo "GOARCH=$goarch" >> $env:GITHUB_ENV 26 | echo "GOROOT=$goroot" >> $env:GITHUB_ENV 27 | echo "GOPATH=$gopath" >> $env:GITHUB_ENV 28 | echo "$goroot/bin" >> $env:GITHUB_PATH 29 | echo "$gopath/bin" >> $env:GITHUB_PATH 30 | New-Item -ItemType "directory" -Name "go" -Path $home 31 | -------------------------------------------------------------------------------- /usage.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/dfinity/keysmith/cmd" 7 | ) 8 | 9 | func Usage() string { 10 | return fmt.Sprintf(`usage: keysmith [] 11 | 12 | Available Commands: 13 | %s Print your account identifier. 14 | %s Generate your mnemonic seed and write it to a file. 15 | %s Print your legacy address. 16 | %s Print your principal identifier. 17 | %s Derive your private key and write it to a file. 18 | %s Print your public key. 19 | %s Print the available commands. 20 | %s Print the version number. 21 | %s Derive your extended private key and write it to a file. 22 | %s Print your extended public key. 23 | `, 24 | cmd.ACCOUNT_CMD, 25 | cmd.GENERATE_CMD, 26 | cmd.LEGACY_ADDRESS_CMD, 27 | cmd.PRINCIPAL_CMD, 28 | cmd.PRIVATE_KEY_CMD, 29 | cmd.PUBLIC_KEY_CMD, 30 | cmd.SHORTLIST_CMD, 31 | cmd.VERSION_CMD, 32 | cmd.X_PRIVATE_KEY_CMD, 33 | cmd.X_PUBLIC_KEY_CMD, 34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v1.6.2 2 | 3 | - **FEATURE:** Add support for seed phrases of different sizes. 4 | 5 | ## v1.6.1 6 | 7 | - **CHORE:** Upgrade encoding library. 8 | 9 | ## v1.6.0 10 | 11 | - **FEATURE:** Add `shortlist` command to print the available commands. 12 | - **FEATURE:** Add `x-private-key` command to derive your extended private key and write it to a file. 13 | - **BUG:** Normalize mnemonic seed input to use the space character as its field separator. 14 | 15 | ## v1.5.0 16 | 17 | - **FEATURE:** Add support for reading files from stdin and writing files to stdout. 18 | 19 | ## v1.4.1 20 | 21 | - **FEATURE:** Add support for Linux on 32-bit ARM. 22 | 23 | ## v1.4.0 24 | 25 | - **FEATURE:** Add support for latest MacOS and Windows. 26 | 27 | ## v1.3.0 28 | 29 | - **CHORE:** Upgrade crypto library. 30 | 31 | ## v1.2.0 32 | 33 | - **FEATURE:** Add `version` command to print the version number. 34 | 35 | ## v1.1.0 36 | 37 | - **FEATURE:** Add `account` command to print your account identifier. 38 | - **BUG:** Rename `address` command to `legacy-address` for brevity. 39 | -------------------------------------------------------------------------------- /cmd/generate.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "flag" 5 | "os" 6 | 7 | "github.com/dfinity/keysmith/util" 8 | "github.com/tyler-smith/go-bip39" 9 | ) 10 | 11 | const GENERATE_CMD = "generate" 12 | 13 | type GenerateCmd struct { 14 | FlagSet *flag.FlagSet 15 | Args *GenerateCmdArgs 16 | } 17 | 18 | type GenerateCmdArgs struct { 19 | Bits *int 20 | OutputFile *string 21 | } 22 | 23 | func NewGenerateCmd() *GenerateCmd { 24 | fset := flag.NewFlagSet(GENERATE_CMD, flag.ExitOnError) 25 | args := &GenerateCmdArgs{ 26 | Bits: fset.Int("b", 128, "Bits of entropy."), 27 | OutputFile: fset.String("o", "seed.txt", "Seed file."), 28 | } 29 | return &GenerateCmd{fset, args} 30 | } 31 | 32 | func (cmd *GenerateCmd) Run() error { 33 | cmd.FlagSet.Parse(os.Args[2:]) 34 | entropy, err := bip39.NewEntropy(*cmd.Args.Bits) 35 | if err != nil { 36 | return err 37 | } 38 | mnemonic, err := bip39.NewMnemonic(entropy) 39 | if err != nil { 40 | return err 41 | } 42 | output := []byte(mnemonic + util.NewLine) 43 | return writeFileOrStdout(*cmd.Args.OutputFile, output, 0600) 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2021 DFINITY Stiftung 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /cmd/x-public-key.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/dfinity/keysmith/crypto" 9 | "github.com/dfinity/keysmith/seed" 10 | ) 11 | 12 | const X_PUBLIC_KEY_CMD = "x-public-key" 13 | 14 | type XPublicKeyCmd struct { 15 | FlagSet *flag.FlagSet 16 | Args *XPublicKeyCmdArgs 17 | } 18 | 19 | type XPublicKeyCmdArgs struct { 20 | SeedFile *string 21 | Protected *bool 22 | } 23 | 24 | func NewXPublicKeyCmd() *XPublicKeyCmd { 25 | fset := flag.NewFlagSet(X_PUBLIC_KEY_CMD, flag.ExitOnError) 26 | args := &XPublicKeyCmdArgs{ 27 | SeedFile: fset.String("f", "seed.txt", "Seed file."), 28 | Protected: fset.Bool("p", false, "Password protection."), 29 | } 30 | return &XPublicKeyCmd{fset, args} 31 | } 32 | 33 | func (cmd *XPublicKeyCmd) Run() error { 34 | cmd.FlagSet.Parse(os.Args[2:]) 35 | seed, err := seed.Load(*cmd.Args.SeedFile, *cmd.Args.Protected) 36 | if err != nil { 37 | return err 38 | } 39 | masterXPrivKey, err := crypto.DeriveMasterXPrivKey(seed) 40 | if err != nil { 41 | return err 42 | } 43 | masterXPubKey, err := masterXPrivKey.Neuter() 44 | if err != nil { 45 | return err 46 | } 47 | output := masterXPubKey.String() 48 | fmt.Println(output) 49 | return nil 50 | } 51 | -------------------------------------------------------------------------------- /quill_migration.md: -------------------------------------------------------------------------------- 1 | # Migrate to [quill](https://github.com/dfinity/quill) 2 | 3 | You can find `quill` equivalents of `keysmith` commands. 4 | 5 | 6 | ## Generate mnemonic seed and private key (PEM) 7 | 8 | ### Before 9 | 10 | ```bash 11 | # Generate mnemonic seed at [seed.txt] 12 | keysmith generate -o seed.txt 13 | # Derive PEM from [seed.txt] at [identity.pem] 14 | keysmith private-key -f seed.txt -o identity.pem 15 | ``` 16 | 17 | ### After 18 | 19 | ```bash 20 | # Generate [seed.txt] and [identity.pem] 21 | # The [Principal id] and [Account id] will also be shown on the console 22 | quill generate --seed-file seed.txt --pem-file identity.pem 23 | # If you already have the seed phrases generated, you can derive PEM with 24 | quill generate --phrase '' --seed-file seed.txt --pem-file identity.pem 25 | ``` 26 | 27 | ## Get principal identifier and/or account id 28 | 29 | ### Before 30 | 31 | ```bash 32 | # Print your principal identifier 33 | keysmith principal -f seed.txt 34 | # Print your account identifier 35 | keysmith account -f seed.txt 36 | ``` 37 | 38 | ### After 39 | 40 | ```bash 41 | # Print principal identifier and account id 42 | quill --seed-file seed.txt public-ids 43 | # or 44 | quill --pem-file identity.pem public-ids 45 | ``` -------------------------------------------------------------------------------- /codec/decode.go: -------------------------------------------------------------------------------- 1 | package codec 2 | 3 | import ( 4 | "encoding/asn1" 5 | "encoding/pem" 6 | "errors" 7 | "fmt" 8 | "io/ioutil" 9 | 10 | "github.com/btcsuite/btcd/btcec" 11 | ) 12 | 13 | func PEMToECPrivKey(data []byte) (*btcec.PrivateKey, error) { 14 | var block *pem.Block 15 | remainder := data 16 | for { 17 | block, remainder = pem.Decode(remainder) 18 | if block == nil { 19 | message := "Cannot find label \"EC PRIVATE KEY\" in PEM data" 20 | return nil, errors.New(message) 21 | } 22 | if block.Type == "EC PRIVATE KEY" { 23 | break 24 | } 25 | } 26 | var object ECPrivKey 27 | _, err := asn1.Unmarshal(block.Bytes, &object) 28 | if err != nil { 29 | return nil, err 30 | } 31 | if !IsSecp256k1(object.NamedCurveOID) { 32 | message := fmt.Sprintf( 33 | "Invalid curve type: %v", 34 | object.NamedCurveOID, 35 | ) 36 | return nil, errors.New(message) 37 | } 38 | privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), object.PrivateKey) 39 | return privKey, nil 40 | } 41 | 42 | func LoadECPrivKey(identityFile string) (*btcec.PrivateKey, error) { 43 | contents, err := ioutil.ReadFile(identityFile) 44 | if err != nil { 45 | return nil, err 46 | } 47 | privKey, err := PEMToECPrivKey(contents) 48 | if err != nil { 49 | return nil, err 50 | } 51 | return privKey, nil 52 | } 53 | -------------------------------------------------------------------------------- /cmd/x-private-key.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "flag" 5 | "os" 6 | 7 | "github.com/dfinity/keysmith/crypto" 8 | "github.com/dfinity/keysmith/seed" 9 | "github.com/dfinity/keysmith/util" 10 | ) 11 | 12 | const X_PRIVATE_KEY_CMD = "x-private-key" 13 | 14 | type XPrivateKeyCmd struct { 15 | FlagSet *flag.FlagSet 16 | Args *XPrivateKeyCmdArgs 17 | } 18 | 19 | type XPrivateKeyCmdArgs struct { 20 | OutputFile *string 21 | SeedFile *string 22 | Protected *bool 23 | } 24 | 25 | func NewXPrivateKeyCmd() *XPrivateKeyCmd { 26 | fset := flag.NewFlagSet(X_PRIVATE_KEY_CMD, flag.ExitOnError) 27 | args := &XPrivateKeyCmdArgs{ 28 | OutputFile: fset.String("o", "identity.bip32", "Output file."), 29 | SeedFile: fset.String("f", "seed.txt", "Seed file."), 30 | Protected: fset.Bool("p", false, "Password protection."), 31 | } 32 | return &XPrivateKeyCmd{fset, args} 33 | } 34 | 35 | func (cmd *XPrivateKeyCmd) Run() error { 36 | cmd.FlagSet.Parse(os.Args[2:]) 37 | seed, err := seed.Load(*cmd.Args.SeedFile, *cmd.Args.Protected) 38 | if err != nil { 39 | return err 40 | } 41 | masterXPrivKey, err := crypto.DeriveMasterXPrivKey(seed) 42 | if err != nil { 43 | return err 44 | } 45 | output := []byte(masterXPrivKey.String() + util.NewLine) 46 | return writeFileOrStdout(*cmd.Args.OutputFile, output, 0600) 47 | } 48 | -------------------------------------------------------------------------------- /principal/principal_test.go: -------------------------------------------------------------------------------- 1 | package principal 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var validIds = [...]string{ 8 | 9 | // Management 10 | "aaaaa-aa", 11 | 12 | // Opaque 13 | "rwlgt-iiaaa-aaaaa-aaaaa-cai", 14 | "rrkah-fqaaa-aaaaa-aaaaq-cai", 15 | "ryjl3-tyaaa-aaaaa-aaaba-cai", 16 | "r7inp-6aaaa-aaaaa-aaabq-cai", 17 | "rkp4c-7iaaa-aaaaa-aaaca-cai", 18 | "rno2w-sqaaa-aaaaa-aaacq-cai", 19 | "renrk-eyaaa-aaaaa-aaada-cai", 20 | "rdmx6-jaaaa-aaaaa-aaadq-cai", 21 | 22 | // Self Authenticating 23 | "t2kpu-6xt6l-tyb3d-rll2p-irv5c-no5nd-h6spj-jsetq-bmqdz-iap77-pqe", 24 | "t2kpu-6xt6l-tyb3d-rll2p-irv5c-no5nd-h6spj-jsetq-bmqdz-iap77-pqe", 25 | "ncpzz-qv6a2-ult3n-4mmvz-gdrhx-ileg4-upz7f-7zfqi-affpy-zlkid-hae", 26 | "oz7pj-bab4p-7iyos-7f3be-i565q-xib6s-pee2u-5l6wx-fexwx-ecv3e-fae", 27 | "xxdyl-bobgu-u3q5w-r67od-b2tc3-mkyv3-m4hlt-5psfn-6rkxt-eyv4x-kae", 28 | "tbl5g-hjbsu-wkhvn-djwco-uztju-cate7-g4p5b-bvqxa-5bg6a-yb6s3-wqe", 29 | "yksvc-462au-rmv5f-w6jlz-7h7ts-pkob5-adhrm-aj7gb-dwylz-3t53y-uae", 30 | "nhiqy-qh3xw-v2s6h-mkwpc-7kmo6-ue3i5-qpjk3-mqfmv-dnvox-hux72-5ae", 31 | "7dm5n-v2brn-p2mla-3t5cw-ppdog-ro5fo-4psh3-zotg2-ix6or-26au2-iae", 32 | 33 | // Anonymous 34 | "2vxsx-fae", 35 | } 36 | 37 | func TestFromString(test *testing.T) { 38 | for _, validId := range validIds { 39 | _, err := FromString(validId) 40 | if err != nil { 41 | test.Fatal(err) 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /cmd/public-key.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "encoding/hex" 5 | "flag" 6 | "fmt" 7 | "os" 8 | 9 | "github.com/dfinity/keysmith/crypto" 10 | "github.com/dfinity/keysmith/seed" 11 | ) 12 | 13 | const PUBLIC_KEY_CMD = "public-key" 14 | 15 | type PublicKeyCmd struct { 16 | FlagSet *flag.FlagSet 17 | Args *PublicKeyCmdArgs 18 | } 19 | 20 | type PublicKeyCmdArgs struct { 21 | SeedFile *string 22 | Index *uint 23 | Protected *bool 24 | } 25 | 26 | func NewPublicKeyCmd() *PublicKeyCmd { 27 | fset := flag.NewFlagSet(PUBLIC_KEY_CMD, flag.ExitOnError) 28 | args := &PublicKeyCmdArgs{ 29 | SeedFile: fset.String("f", "seed.txt", "Seed file."), 30 | Index: fset.Uint("i", 0, "Derivation index."), 31 | Protected: fset.Bool("p", false, "Password protection."), 32 | } 33 | return &PublicKeyCmd{fset, args} 34 | } 35 | 36 | func (cmd *PublicKeyCmd) Run() error { 37 | cmd.FlagSet.Parse(os.Args[2:]) 38 | seed, err := seed.Load(*cmd.Args.SeedFile, *cmd.Args.Protected) 39 | if err != nil { 40 | return err 41 | } 42 | masterXPrivKey, err := crypto.DeriveMasterXPrivKey(seed) 43 | if err != nil { 44 | return err 45 | } 46 | _, grandchildECPubKey, err := crypto.DeriveGrandchildECKeyPair( 47 | masterXPrivKey, 48 | uint32(*cmd.Args.Index), 49 | ) 50 | if err != nil { 51 | return err 52 | } 53 | output := hex.EncodeToString(grandchildECPubKey.SerializeUncompressed()) 54 | fmt.Println(output) 55 | return nil 56 | } 57 | -------------------------------------------------------------------------------- /crypto/crypto.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "github.com/btcsuite/btcd/btcec" 5 | "github.com/btcsuite/btcd/chaincfg" 6 | "github.com/dfinity/go-hdkeychain" 7 | "github.com/ethereum/go-ethereum/accounts" 8 | ) 9 | 10 | const DerivationPath = "m/44'/223'/0'" 11 | 12 | func DeriveMasterXPrivKey(seed []byte) (*hdkeychain.ExtendedKey, error) { 13 | masterXPrivKey, err := hdkeychain.NewMaster( 14 | seed, 15 | &chaincfg.MainNetParams, 16 | ) 17 | if err != nil { 18 | return nil, err 19 | } 20 | path, err := accounts.ParseDerivationPath(DerivationPath) 21 | if err != nil { 22 | return nil, err 23 | } 24 | for _, i := range path { 25 | masterXPrivKey, err = masterXPrivKey.Derive(i) 26 | if err != nil { 27 | return nil, err 28 | } 29 | } 30 | return masterXPrivKey, nil 31 | } 32 | 33 | func DeriveGrandchildECKeyPair( 34 | masterXPrivKey *hdkeychain.ExtendedKey, 35 | i uint32, 36 | ) (*btcec.PrivateKey, *btcec.PublicKey, error) { 37 | // First apply the change. 38 | childXPrivKey, err := masterXPrivKey.Derive(0) 39 | if err != nil { 40 | return nil, nil, err 41 | } 42 | grandchildXPrivKey, err := childXPrivKey.Derive(i) 43 | if err != nil { 44 | return nil, nil, err 45 | } 46 | grandchildECPrivKey, err := grandchildXPrivKey.ECPrivKey() 47 | if err != nil { 48 | return nil, nil, err 49 | } 50 | grandchildECPubKey := grandchildECPrivKey.PubKey() 51 | return grandchildECPrivKey, grandchildECPubKey, nil 52 | } 53 | -------------------------------------------------------------------------------- /cmd/account.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/dfinity/keysmith/account" 9 | "github.com/dfinity/keysmith/crypto" 10 | "github.com/dfinity/keysmith/seed" 11 | ) 12 | 13 | const ACCOUNT_CMD = "account" 14 | 15 | type AccountCmd struct { 16 | FlagSet *flag.FlagSet 17 | Args *AccountCmdArgs 18 | } 19 | 20 | type AccountCmdArgs struct { 21 | SeedFile *string 22 | Index *uint 23 | Protected *bool 24 | } 25 | 26 | func NewAccountCmd() *AccountCmd { 27 | fset := flag.NewFlagSet(ACCOUNT_CMD, flag.ExitOnError) 28 | args := &AccountCmdArgs{ 29 | SeedFile: fset.String("f", "seed.txt", "Seed file."), 30 | Index: fset.Uint("i", 0, "Derivation index."), 31 | Protected: fset.Bool("p", false, "Password protection."), 32 | } 33 | return &AccountCmd{fset, args} 34 | } 35 | 36 | func (cmd *AccountCmd) Run() error { 37 | cmd.FlagSet.Parse(os.Args[2:]) 38 | seed, err := seed.Load(*cmd.Args.SeedFile, *cmd.Args.Protected) 39 | if err != nil { 40 | return err 41 | } 42 | masterXPrivKey, err := crypto.DeriveMasterXPrivKey(seed) 43 | if err != nil { 44 | return err 45 | } 46 | _, grandchildECPubKey, err := crypto.DeriveGrandchildECKeyPair( 47 | masterXPrivKey, 48 | uint32(*cmd.Args.Index), 49 | ) 50 | if err != nil { 51 | return err 52 | } 53 | accountId, err := account.FromECPubKey(grandchildECPubKey) 54 | if err != nil { 55 | return err 56 | } 57 | fmt.Println(accountId.String()) 58 | return nil 59 | } 60 | -------------------------------------------------------------------------------- /cmd/principal.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/dfinity/keysmith/crypto" 9 | "github.com/dfinity/keysmith/principal" 10 | "github.com/dfinity/keysmith/seed" 11 | ) 12 | 13 | const PRINCIPAL_CMD = "principal" 14 | 15 | type PrincipalCmd struct { 16 | FlagSet *flag.FlagSet 17 | Args *PrincipalCmdArgs 18 | } 19 | 20 | type PrincipalCmdArgs struct { 21 | SeedFile *string 22 | Index *uint 23 | Protected *bool 24 | } 25 | 26 | func NewPrincipalCmd() *PrincipalCmd { 27 | fset := flag.NewFlagSet(PRINCIPAL_CMD, flag.ExitOnError) 28 | args := &PrincipalCmdArgs{ 29 | SeedFile: fset.String("f", "seed.txt", "Seed file."), 30 | Index: fset.Uint("i", 0, "Derivation index."), 31 | Protected: fset.Bool("p", false, "Password protection."), 32 | } 33 | return &PrincipalCmd{fset, args} 34 | } 35 | 36 | func (cmd *PrincipalCmd) Run() error { 37 | cmd.FlagSet.Parse(os.Args[2:]) 38 | seed, err := seed.Load(*cmd.Args.SeedFile, *cmd.Args.Protected) 39 | if err != nil { 40 | return err 41 | } 42 | masterXPrivKey, err := crypto.DeriveMasterXPrivKey(seed) 43 | if err != nil { 44 | return err 45 | } 46 | _, grandchildECPubKey, err := crypto.DeriveGrandchildECKeyPair( 47 | masterXPrivKey, 48 | uint32(*cmd.Args.Index), 49 | ) 50 | if err != nil { 51 | return err 52 | } 53 | principalId, err := principal.FromECPubKey(grandchildECPubKey) 54 | if err != nil { 55 | return err 56 | } 57 | fmt.Println(principalId.String()) 58 | return nil 59 | } 60 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/dfinity/keysmith/cmd" 8 | "github.com/dfinity/keysmith/util" 9 | ) 10 | 11 | var ( 12 | MAJOR = "0" 13 | MINOR = "0" 14 | PATCH = "0" 15 | BUILD = "unknown" 16 | ) 17 | 18 | func main() { 19 | 20 | // Check if a subcommand was provided. 21 | if len(os.Args) < 2 { 22 | fmt.Fprintf(os.Stdout, Usage()) 23 | os.Exit(0) 24 | } 25 | 26 | // Run the subcommand. 27 | var err error 28 | switch os.Args[1] { 29 | case cmd.ACCOUNT_CMD: 30 | err = cmd.NewAccountCmd().Run() 31 | case cmd.GENERATE_CMD: 32 | err = cmd.NewGenerateCmd().Run() 33 | case cmd.LEGACY_ADDRESS_CMD: 34 | err = cmd.NewLegacyAddressCmd().Run() 35 | case cmd.PRINCIPAL_CMD: 36 | err = cmd.NewPrincipalCmd().Run() 37 | case cmd.PRIVATE_KEY_CMD: 38 | err = cmd.NewPrivateKeyCmd().Run() 39 | case cmd.PUBLIC_KEY_CMD: 40 | err = cmd.NewPublicKeyCmd().Run() 41 | case cmd.SHORTLIST_CMD: 42 | err = cmd.NewShortlistCmd().Run() 43 | case cmd.VERSION_CMD: 44 | err = cmd.NewVersionCmd(version()).Run() 45 | case cmd.X_PRIVATE_KEY_CMD: 46 | err = cmd.NewXPrivateKeyCmd().Run() 47 | case cmd.X_PUBLIC_KEY_CMD: 48 | err = cmd.NewXPublicKeyCmd().Run() 49 | default: 50 | fmt.Fprintf(os.Stderr, Usage()) 51 | os.Exit(1) 52 | } 53 | 54 | // Check if an error occurred. 55 | if err != nil { 56 | fmt.Fprintf(os.Stderr, "Error: %v%s", err, util.NewLine) 57 | os.Exit(1) 58 | } 59 | } 60 | 61 | func version() string { 62 | return fmt.Sprintf("%s.%s.%s-%s", MAJOR, MINOR, PATCH, BUILD) 63 | } 64 | -------------------------------------------------------------------------------- /cmd/legacy-address.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "strings" 8 | 9 | "github.com/dfinity/keysmith/crypto" 10 | "github.com/dfinity/keysmith/seed" 11 | eth "github.com/ethereum/go-ethereum/crypto" 12 | ) 13 | 14 | const LEGACY_ADDRESS_CMD = "legacy-address" 15 | 16 | type LegacyAddressCmd struct { 17 | FlagSet *flag.FlagSet 18 | Args *LegacyAddressCmdArgs 19 | } 20 | 21 | type LegacyAddressCmdArgs struct { 22 | SeedFile *string 23 | Index *uint 24 | Protected *bool 25 | } 26 | 27 | func NewLegacyAddressCmd() *LegacyAddressCmd { 28 | fset := flag.NewFlagSet(LEGACY_ADDRESS_CMD, flag.ExitOnError) 29 | args := &LegacyAddressCmdArgs{ 30 | SeedFile: fset.String("f", "seed.txt", "Seed file."), 31 | Index: fset.Uint("i", 0, "Derivation index."), 32 | Protected: fset.Bool("p", false, "Password protection."), 33 | } 34 | return &LegacyAddressCmd{fset, args} 35 | } 36 | 37 | func (cmd *LegacyAddressCmd) Run() error { 38 | cmd.FlagSet.Parse(os.Args[2:]) 39 | seed, err := seed.Load(*cmd.Args.SeedFile, *cmd.Args.Protected) 40 | if err != nil { 41 | return err 42 | } 43 | masterXPrivKey, err := crypto.DeriveMasterXPrivKey(seed) 44 | if err != nil { 45 | return err 46 | } 47 | _, grandchildECPubKey, err := crypto.DeriveGrandchildECKeyPair( 48 | masterXPrivKey, 49 | uint32(*cmd.Args.Index), 50 | ) 51 | if err != nil { 52 | return err 53 | } 54 | address := eth.PubkeyToAddress(*grandchildECPubKey.ToECDSA()) 55 | output := strings.ToLower(strings.TrimPrefix(address.String(), "0x")) 56 | fmt.Println(output) 57 | return nil 58 | } 59 | -------------------------------------------------------------------------------- /cmd/private-key.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "flag" 5 | "os" 6 | 7 | "github.com/dfinity/keysmith/codec" 8 | "github.com/dfinity/keysmith/crypto" 9 | "github.com/dfinity/keysmith/seed" 10 | ) 11 | 12 | const PRIVATE_KEY_CMD = "private-key" 13 | 14 | type PrivateKeyCmd struct { 15 | FlagSet *flag.FlagSet 16 | Args *PrivateKeyCmdArgs 17 | } 18 | 19 | type PrivateKeyCmdArgs struct { 20 | Index *uint 21 | OutputFile *string 22 | Protected *bool 23 | SeedFile *string 24 | } 25 | 26 | func NewPrivateKeyCmd() *PrivateKeyCmd { 27 | fset := flag.NewFlagSet(PRIVATE_KEY_CMD, flag.ExitOnError) 28 | args := &PrivateKeyCmdArgs{ 29 | Index: fset.Uint("i", 0, "Derivation index."), 30 | OutputFile: fset.String("o", "identity.pem", "Output file."), 31 | Protected: fset.Bool("p", false, "Password protection."), 32 | SeedFile: fset.String("f", "seed.txt", "Seed file."), 33 | } 34 | return &PrivateKeyCmd{fset, args} 35 | } 36 | 37 | func (cmd *PrivateKeyCmd) Run() error { 38 | cmd.FlagSet.Parse(os.Args[2:]) 39 | seed, err := seed.Load(*cmd.Args.SeedFile, *cmd.Args.Protected) 40 | if err != nil { 41 | return err 42 | } 43 | masterXPrivKey, err := crypto.DeriveMasterXPrivKey(seed) 44 | if err != nil { 45 | return err 46 | } 47 | grandchildECPrivKey, _, err := crypto.DeriveGrandchildECKeyPair( 48 | masterXPrivKey, 49 | uint32(*cmd.Args.Index), 50 | ) 51 | if err != nil { 52 | return err 53 | } 54 | output, err := codec.ECPrivKeyToPEM(grandchildECPrivKey) 55 | if err != nil { 56 | return err 57 | } 58 | return writeFileOrStdout(*cmd.Args.OutputFile, output, 0600) 59 | } 60 | -------------------------------------------------------------------------------- /codec/encode.go: -------------------------------------------------------------------------------- 1 | package codec 2 | 3 | import ( 4 | "crypto/elliptic" 5 | "encoding/asn1" 6 | "encoding/pem" 7 | 8 | "github.com/btcsuite/btcd/btcec" 9 | ) 10 | 11 | func ECPrivKeyToPEM(privKey *btcec.PrivateKey) ([]byte, error) { 12 | der1, err := EncodeECParams() 13 | if err != nil { 14 | return nil, err 15 | } 16 | der2, err := EncodeECPrivKey(privKey) 17 | if err != nil { 18 | return nil, err 19 | } 20 | block1 := &pem.Block{ 21 | Type: "EC PARAMETERS", 22 | Bytes: der1, 23 | } 24 | block2 := &pem.Block{ 25 | Type: "EC PRIVATE KEY", 26 | Bytes: der2, 27 | } 28 | data1 := pem.EncodeToMemory(block1) 29 | data2 := pem.EncodeToMemory(block2) 30 | return append(data1, data2...), nil 31 | } 32 | 33 | func EncodeECParams() ([]byte, error) { 34 | return asn1.Marshal(Secp256k1()) 35 | } 36 | 37 | func EncodeECPrivKey(privKey *btcec.PrivateKey) ([]byte, error) { 38 | curve := btcec.S256() 39 | point := privKey.PubKey().ToECDSA() 40 | return asn1.Marshal(ECPrivKey{ 41 | Version: 1, 42 | PrivateKey: privKey.D.Bytes(), 43 | NamedCurveOID: Secp256k1(), 44 | PublicKey: asn1.BitString{ 45 | Bytes: elliptic.Marshal(curve, point.X, point.Y), 46 | }, 47 | }) 48 | } 49 | 50 | func EncodeECPubKey(pubKey *btcec.PublicKey) ([]byte, error) { 51 | curve := btcec.S256() 52 | point := pubKey.ToECDSA() 53 | return asn1.Marshal(ECPubKey{ 54 | Metadata: []asn1.ObjectIdentifier{ 55 | asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}, 56 | Secp256k1(), 57 | }, 58 | PublicKey: asn1.BitString{ 59 | Bytes: elliptic.Marshal(curve, point.X, point.Y), 60 | }, 61 | }) 62 | } 63 | 64 | func EncodeECSig(sig *btcec.Signature) []byte { 65 | var buf [64]byte 66 | r := sig.R.Bytes() 67 | s := sig.S.Bytes() 68 | copy(buf[(32-len(r)):], r) 69 | copy(buf[(64-len(s)):], s) 70 | return buf[:] 71 | } 72 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | jobs: 8 | keysmith-darwin: 9 | runs-on: ${{ matrix.os }} 10 | strategy: 11 | matrix: 12 | os: 13 | - macos-10.15 14 | - macos-latest 15 | steps: 16 | - uses: actions/checkout@v1 17 | - name: 'Install Bats Core' 18 | run: ./.github/workflows/install/darwin/bats-core.sh 19 | - name: 'Install Bats Support' 20 | run: ./.github/workflows/install/darwin/bats-support.sh 21 | - name: 'Install Go' 22 | run: ./.github/workflows/install/darwin/go.sh 23 | - name: 'Install Go Packages' 24 | run: go get ./... 25 | - name: 'Build Keysmith' 26 | run: go build 27 | - name: 'Test Keysmith' 28 | run: bats e2e/bash/test.bats 29 | keysmith-linux: 30 | runs-on: ${{ matrix.os }} 31 | strategy: 32 | matrix: 33 | os: 34 | - ubuntu-18.04 35 | - ubuntu-20.04 36 | - ubuntu-latest 37 | steps: 38 | - uses: actions/checkout@v1 39 | - name: 'Install Bats Core' 40 | run: ./.github/workflows/install/linux/bats-core.sh 41 | - name: 'Install Bats Support' 42 | run: ./.github/workflows/install/linux/bats-support.sh 43 | - name: 'Install Go' 44 | run: ./.github/workflows/install/linux/go.sh 45 | - name: 'Install Go Packages' 46 | run: go get ./... 47 | - name: 'Build Keysmith' 48 | run: go build 49 | - name: 'Test Keysmith' 50 | run: bats e2e/bash/test.bats 51 | keysmith-windows: 52 | runs-on: ${{ matrix.os }} 53 | strategy: 54 | matrix: 55 | os: 56 | - windows-2016 57 | - windows-2019 58 | - windows-latest 59 | steps: 60 | - uses: actions/checkout@v1 61 | - name: 'Install Go' 62 | run: .\.github\workflows\install\windows\go.ps1 63 | - name: 'Install Go Packages' 64 | run: go get ./... 65 | - name: 'Build Keysmith' 66 | run: go build 67 | - name: 'Test Keysmith' 68 | run: Invoke-Pester e2e\powershell\test.ps1 69 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MAJOR ?= 1 2 | MINOR ?= 6 3 | PATCH ?= 2 4 | 5 | LDFLAGS := -X=main.MAJOR=$(MAJOR) 6 | LDFLAGS += -X=main.MINOR=$(MINOR) 7 | LDFLAGS += -X=main.PATCH=$(PATCH) 8 | 9 | PRIVATE_KEY ?= $(HOME)/.openssl/private.key 10 | 11 | .PHONY: all 12 | all: build 13 | 14 | .PHONY: build 15 | build: 16 | $(eval BUILD ?= $(shell git describe --always --dirty)) 17 | $(eval LDFLAGS += -X=main.BUILD=$(BUILD)) 18 | $(eval GOFLAGS := -ldflags="$(LDFLAGS)") 19 | go build $(GOFLAGS) 20 | 21 | .PHONY: release 22 | release: 23 | $(eval BUILD ?= release) 24 | $(eval LDFLAGS += -X=main.BUILD=$(BUILD)) 25 | $(eval GOFLAGS := -ldflags="$(LDFLAGS)") 26 | 27 | # Create release directory. 28 | mkdir -p release 29 | 30 | # Create checksum file. 31 | > SHA256.SUM 32 | 33 | # Create release script for tab completions. 34 | openssl dgst -sha256 keysmith-completions.bash >> SHA256.SUM 35 | cp keysmith-completions.bash release 36 | 37 | # Create release tarball for darwin/amd64. 38 | GOOS=darwin GOARCH=amd64 go build $(GOFLAGS) 39 | tar -c -f keysmith-darwin-amd64.tar.gz -z keysmith 40 | openssl dgst -sha256 keysmith-darwin-amd64.tar.gz >> SHA256.SUM 41 | mv keysmith-darwin-amd64.tar.gz release 42 | 43 | # Create release tarball for darwin/arm64. 44 | GOOS=darwin GOARCH=arm64 go build $(GOFLAGS) 45 | tar -c -f keysmith-darwin-arm64.tar.gz -z keysmith 46 | openssl dgst -sha256 keysmith-darwin-arm64.tar.gz >> SHA256.SUM 47 | mv keysmith-darwin-arm64.tar.gz release 48 | 49 | # Create release tarball for linux/amd64. 50 | GOOS=linux GOARCH=amd64 go build $(GOFLAGS) 51 | tar -c -f keysmith-linux-amd64.tar.gz -z keysmith 52 | openssl dgst -sha256 keysmith-linux-amd64.tar.gz >> SHA256.SUM 53 | mv keysmith-linux-amd64.tar.gz release 54 | 55 | # Create release tarball for linux/arm32. 56 | GOOS=linux GOARCH=arm go build $(GOFLAGS) 57 | tar -c -f keysmith-linux-arm32.tar.gz -z keysmith 58 | openssl dgst -sha256 keysmith-linux-arm32.tar.gz >> SHA256.SUM 59 | mv keysmith-linux-arm32.tar.gz release 60 | 61 | # Create release tarball for linux/arm64. 62 | GOOS=linux GOARCH=arm64 go build $(GOFLAGS) 63 | tar -c -f keysmith-linux-arm64.tar.gz -z keysmith 64 | openssl dgst -sha256 keysmith-linux-arm64.tar.gz >> SHA256.SUM 65 | mv keysmith-linux-arm64.tar.gz release 66 | 67 | # Create release tarball for windows/amd64. 68 | GOOS=windows GOARCH=amd64 go build $(GOFLAGS) 69 | tar -c -f keysmith-windows-amd64.tar.gz -z keysmith.exe 70 | openssl dgst -sha256 keysmith-windows-amd64.tar.gz >> SHA256.SUM 71 | mv keysmith-windows-amd64.tar.gz release 72 | 73 | # Sign release scripts and tarballs. 74 | openssl dgst -out SHA256.SIG -sha256 -sign $(PRIVATE_KEY) SHA256.SUM 75 | mv SHA256.SIG SHA256.SUM release 76 | 77 | .PHONY: clean 78 | clean: 79 | rm -f -r keysmith keysmith.exe release 80 | -------------------------------------------------------------------------------- /e2e/bash/util/assert.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Asserts that a command succeeds. 4 | # 5 | # Arguments: 6 | # $@ - The command to run. 7 | # 8 | # Returns: 9 | # none 10 | assert_command() { 11 | local stderrf="$(mktemp)" 12 | local stdoutf="$(mktemp)" 13 | local statusf="$(mktemp)" 14 | ( set +e; "$@" 2>"$stderrf" >"$stdoutf"; echo -n "$?" > "$statusf" ) 15 | status="$(<$statusf)"; rm "$statusf" 16 | stderr="$(cat $stderrf)"; rm "$stderrf" 17 | stdout="$(cat $stdoutf)"; rm "$stdoutf" 18 | output="$( 19 | [ "$stderr" ] && echo $stderr || true; 20 | [ "$stdout" ] && echo $stdout || true; 21 | )" 22 | [[ $status == 0 ]] || \ 23 | ( (echo "$*"; echo "status: $status"; echo "$output" | batslib_decorate "Output") \ 24 | | batslib_decorate "Command failed" \ 25 | | fail) 26 | } 27 | 28 | # Asserts that a command fails. 29 | # 30 | # Arguments: 31 | # $@ - The command to run. 32 | # 33 | # Returns: 34 | # none 35 | assert_command_fail() { 36 | local stderrf="$(mktemp)" 37 | local stdoutf="$(mktemp)" 38 | local statusf="$(mktemp)" 39 | ( set +e; "$@" 2>"$stderrf" >"$stdoutf"; echo -n "$?" > "$statusf" ) 40 | status="$(<$statusf)"; rm "$statusf" 41 | stderr="$(cat $stderrf)"; rm "$stderrf" 42 | stdout="$(cat $stdoutf)"; rm "$stdoutf" 43 | output="$( 44 | [ "$stderr" ] && echo $stderr || true; 45 | [ "$stdout" ] && echo $stdout || true; 46 | )" 47 | [[ $status != 0 ]] || \ 48 | ( (echo "$*"; echo "status: $status"; echo "$output" | batslib_decorate "Output") \ 49 | | batslib_decorate "Command succeeded (should have failed)" \ 50 | | fail) 51 | } 52 | 53 | # Asserts that a phrase matches a regular expression. 54 | # 55 | # Arguments: 56 | # $1 - The regular expression. 57 | # $2 - The phrase to match against. Defaults to $output. 58 | assert_match() { 59 | regex="$1" 60 | if [[ $# < 2 ]]; then 61 | text="$output" 62 | else 63 | text="$2" 64 | fi 65 | [[ "$text" =~ $regex ]] || \ 66 | (batslib_print_kv_single_or_multi 10 "regex" "$regex" "actual" "$text" \ 67 | | batslib_decorate "output does not match" \ 68 | | fail) 69 | } 70 | 71 | # Asserts that two values are equal. 72 | # 73 | # Arguments: 74 | # $1 - The expected value. 75 | # $2 - The actual value. Defaults to $output. 76 | assert_eq() { 77 | expected="$1" 78 | if [[ $# < 2 ]]; then 79 | actual="$output" 80 | else 81 | actual="$2" 82 | fi 83 | [[ "$actual" == "$expected" ]] || \ 84 | (batslib_print_kv_single_or_multi 10 "expected" "$expected" "actual" "$actual" \ 85 | | batslib_decorate "output does not match" \ 86 | | fail) 87 | } 88 | 89 | # Asserts that two values are not equal. 90 | # 91 | # Arguments: 92 | # $1 - The expected value. 93 | # $2 - The actual value. Defaults to $output. 94 | assert_neq() { 95 | expected="$1" 96 | if [[ $# < 2 ]]; then 97 | actual="$output" 98 | else 99 | actual="$2" 100 | fi 101 | [[ "$actual" != "$expected" ]] || \ 102 | (batslib_print_kv_single_or_multi 10 "expected" "$expected" "actual" "$actual" \ 103 | | batslib_decorate "output does not match" \ 104 | | fail) 105 | } 106 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Migrate to [quill](https://github.com/dfinity/quill) 2 | 3 | To provide a unified user experience, we recommand [`quill`](https://github.com/dfinity/quill) which provide more comprehensive support for ledger and governance on the Internet Computer. 4 | 5 | We will not add new features to `keysmith` or release new versions. 6 | 7 | Please refer to this [migration guide](quill_migration.md) to get the `quill` equivalents of `keysmith` commands. 8 | 9 | Note that some sophasicated functionalities are not available in quill yet. If your workflow relies on those `keysmith` commands, you can keep using it. 10 | 11 | # Keysmith 12 | 13 | Hierarchical Deterministic Key Derivation for the Internet Computer 14 | 15 | [![Build Status](https://github.com/dfinity/keysmith/workflows/build/badge.svg)](https://github.com/dfinity/keysmith/actions?query=workflow%3Abuild) 16 | 17 | ## Disclaimer 18 | 19 | YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT USE OF THIS SOFTWARE IS AT YOUR SOLE RISK. AUTHORS OF THIS SOFTWARE SHALL NOT BE LIABLE FOR DAMAGES OF ANY TYPE, WHETHER DIRECT OR INDIRECT. 20 | 21 | ## Introduction 22 | 23 | Keysmith lets you derive cryptographic keys and identifiers for the Internet Computer. Among these identifiers includes an account identifier, which indicates the source or destination of an ICP token transfer. Keysmith does not sign or send messages to the Internet Computer. Hence, Keysmith does not facilitate ICP token transfer, but rather only ICP token custody. For use cases other than custody, such as payments, consider using Keysmith in conjunction with other software, such as the [DFINITY Canister SDK](https://github.com/dfinity/keysmith#integration-with-the-dfinity-canister-sdk). 24 | 25 | ## Download 26 | 27 | Download the latest tarball [here](https://github.com/dfinity/keysmith/releases). 28 | 29 | ## Verify 30 | 31 | If you want to verify the authenticity of the tarball, then please also download the supplementary `SHA256.SIG` and `SHA256.SUM` files, as well as my public key, which you can find [here](https://sovereign.io/public.key). 32 | 33 | Verify the SHA256 checksum of the tarball. 34 | 35 | ```text 36 | grep "$(openssl dgst -sha256 keysmith-*.tar.gz)" SHA256.SUM 37 | ``` 38 | 39 | Verify the signature on the tarball. 40 | 41 | ```text 42 | openssl dgst -sha256 -verify public.key -signature SHA256.SIG SHA256.SUM 43 | ``` 44 | 45 | The command above should display the following output. 46 | 47 | ```text 48 | Verified OK 49 | ``` 50 | 51 | ## Install 52 | 53 | Extract the executable from the tarball. 54 | 55 | ```text 56 | tar -f keysmith-*.tar.gz -x 57 | ``` 58 | 59 | Add the executable to your `PATH`. 60 | 61 | ```text 62 | sudo install -d /usr/local/bin 63 | sudo install keysmith /usr/local/bin 64 | ``` 65 | 66 | ## Usage 67 | 68 | Below is list of commands and their behavior. 69 | 70 | - `account` prints your account identifier. 71 | - `generate` generates your mnemonic seed and writes it to a file. 72 | - `legacy-address` prints your legacy address. 73 | - `principal` prints your principal identifier. 74 | - `private-key` derives your private key and writes it to a file. 75 | - `public-key` prints your public key. 76 | - `shortlist` prints the available commands. 77 | - `version` prints the version number. 78 | - `x-private-key` derives your extended private key and writes it to a file. 79 | - `x-public-key` prints your extended public key. 80 | 81 | ## Integration with the DFINITY Canister SDK 82 | 83 | The [DFINITY Canister SDK](https://sdk.dfinity.org) can sign and send messages to the Internet Computer. Versions `0.7.0-beta.6` and greater provide a convenient `ledger` command that facilitates ICP token transfer. Consider the workflow below. 84 | 85 | ```bash 86 | # Generate your mnemonic seed. 87 | keysmith generate 88 | # Derive your private key. 89 | keysmith private-key 90 | # Create an empty project. 91 | echo {} > dfx.json 92 | # Import your private key. 93 | dfx identity import alternate identity.pem 94 | # Use your private key to sign messages. 95 | dfx identity use alternate 96 | # Print your account identifier. 97 | dfx ledger account-id 98 | # Check your balance. 99 | dfx ledger --network=https://ic0.app balance 100 | # Send me some tokens. 101 | dfx ledger --network=https://ic0.app transfer \ 102 | --amount=1.23456789 \ 103 | --memo=0 \ 104 | --to=89e99f79ec4d81f77a6c8cb243e536e7b3244d7294fb803bcd77b3dd4e32ae36 105 | ``` 106 | -------------------------------------------------------------------------------- /principal/principal.go: -------------------------------------------------------------------------------- 1 | package principal 2 | 3 | import ( 4 | "bytes" 5 | "crypto/sha256" 6 | "encoding/base32" 7 | "encoding/binary" 8 | "fmt" 9 | "hash/crc32" 10 | "strings" 11 | 12 | "github.com/btcsuite/btcd/btcec" 13 | "github.com/dfinity/keysmith/codec" 14 | ) 15 | 16 | type PrincipalId interface { 17 | Bytes() []byte 18 | String() string 19 | } 20 | 21 | type ManagementId struct{} 22 | 23 | func (principalId *ManagementId) Bytes() []byte { 24 | return nil 25 | } 26 | 27 | func (principalId *ManagementId) String() string { 28 | return show(nil) 29 | } 30 | 31 | type OpaqueId struct { 32 | data []byte 33 | } 34 | 35 | func (principalId *OpaqueId) Bytes() []byte { 36 | return principalId.data 37 | } 38 | 39 | func (principalId *OpaqueId) String() string { 40 | return show(principalId.data) 41 | } 42 | 43 | type SelfAuthenticatingId struct { 44 | data []byte 45 | } 46 | 47 | func NewSelfAuthenticatingId(der []byte) PrincipalId { 48 | hash := sha256.Sum224(der) 49 | data := append(hash[:], []byte{2}...) 50 | return &SelfAuthenticatingId{data: data} 51 | } 52 | 53 | func FromECPubKey(pubKey *btcec.PublicKey) (PrincipalId, error) { 54 | der, err := codec.EncodeECPubKey(pubKey) 55 | if err != nil { 56 | return nil, err 57 | } 58 | return NewSelfAuthenticatingId(der), nil 59 | } 60 | 61 | func (principalId *SelfAuthenticatingId) Bytes() []byte { 62 | return principalId.data 63 | } 64 | 65 | func (principalId *SelfAuthenticatingId) String() string { 66 | return show(principalId.data) 67 | } 68 | 69 | type DerivedId struct { 70 | data []byte 71 | } 72 | 73 | func (principalId *DerivedId) Bytes() []byte { 74 | return principalId.data 75 | } 76 | 77 | func (principalId *DerivedId) String() string { 78 | return show(principalId.data) 79 | } 80 | 81 | type AnonymousId struct{} 82 | 83 | func (principalId *AnonymousId) Bytes() []byte { 84 | return []byte{4} 85 | } 86 | 87 | func (principalId *AnonymousId) String() string { 88 | return show([]byte{4}) 89 | } 90 | 91 | type UnassignedId struct { 92 | data []byte 93 | } 94 | 95 | func (principalId *UnassignedId) Bytes() []byte { 96 | return principalId.data 97 | } 98 | 99 | func (principalId *UnassignedId) String() string { 100 | return show(principalId.data) 101 | } 102 | 103 | func FromString(str string) (PrincipalId, error) { 104 | 105 | // Decode. 106 | decoder := base32.StdEncoding.WithPadding(base32.NoPadding) 107 | str32 := strings.ToUpper(strings.Replace(str, "-", "", -1)) 108 | envelope, err := decoder.DecodeString(str32) 109 | if err != nil { 110 | return nil, err 111 | } 112 | 113 | // Check length. 114 | if len(envelope) < 4 { 115 | msg := "Invalid principal identifier: Invalid length: %s" 116 | return nil, fmt.Errorf(msg, str) 117 | } 118 | 119 | // Check checksum. 120 | reader := bytes.NewReader(envelope[0:4]) 121 | var expect uint32 122 | binary.Read(reader, binary.BigEndian, &expect) 123 | data := envelope[4:] 124 | actual := crc32.ChecksumIEEE(data) 125 | if expect != actual { 126 | msg := "Invalid principal identifier: Invalid checksum: %s" 127 | return nil, fmt.Errorf(msg, str) 128 | } 129 | 130 | // Match type. 131 | var principalId PrincipalId 132 | if len(data) == 0 { 133 | principalId = &ManagementId{} 134 | } else { 135 | switch data[len(data)-1] { 136 | case 1: 137 | principalId = &OpaqueId{data: data} 138 | case 2: 139 | principalId = &SelfAuthenticatingId{data: data} 140 | case 3: 141 | principalId = &DerivedId{data: data} 142 | case 4: 143 | principalId = &AnonymousId{} 144 | default: 145 | principalId = &UnassignedId{data: data} 146 | } 147 | } 148 | 149 | // Check textual format. 150 | if str != principalId.String() { 151 | msg := "Invalid principal identifier: Abnormal textual format: %s" 152 | return nil, fmt.Errorf(msg, str) 153 | } 154 | 155 | // Return. 156 | return principalId, nil 157 | } 158 | 159 | func show(data []byte) string { 160 | crc := make([]byte, 4) 161 | binary.BigEndian.PutUint32(crc, crc32.ChecksumIEEE(data)) 162 | encoder := base32.StdEncoding.WithPadding(base32.NoPadding) 163 | str := encoder.EncodeToString(append(crc, data...)) 164 | return strings.Join(split(strings.ToLower(str), 5), "-") 165 | } 166 | 167 | func split(str string, n int) []string { 168 | if n >= len(str) { 169 | return []string{str} 170 | } 171 | var chunks []string 172 | chunk := make([]rune, n) 173 | i := 0 174 | for _, r := range str { 175 | chunk[i] = r 176 | i++ 177 | if i == n { 178 | chunks = append(chunks, string(chunk)) 179 | i = 0 180 | } 181 | } 182 | if i > 0 { 183 | chunks = append(chunks, string(chunk[:i])) 184 | } 185 | return chunks 186 | } 187 | -------------------------------------------------------------------------------- /e2e/bash/test.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | source $BATS_SUPPORT/load.bash 4 | 5 | load util/_ 6 | load util/assert 7 | 8 | setup() { 9 | cd $(mktemp -d -t keysmith-e2e-XXXXXXXX) 10 | echo 'verb bottom twelve symptom plastic believe beach cargo inherit viable dice loop' > seed.txt 11 | } 12 | 13 | teardown() { 14 | rm seed.txt 15 | } 16 | 17 | @test "Can print the version number" { 18 | assert_command $keysmith version 19 | assert_match "^[0-9]+\.[0-9]+\.[0-9]+-[0-9a-z\-]+$" 20 | } 21 | 22 | @test "Can generate the seed phrase" { 23 | assert_command $keysmith generate -o=alternate.txt 24 | assert_command cat alternate.txt 25 | assert_match "^([a-z]+( |$)){12}" 26 | assert_command $keysmith generate -b=128 -o=alternate12.txt 27 | assert_command cat alternate12.txt 28 | assert_match "^([a-z]+( |$)){12}" 29 | assert_command $keysmith generate -b=160 -o=alternate15.txt 30 | assert_command cat alternate15.txt 31 | assert_match "^([a-z]+( |$)){15}" 32 | assert_command $keysmith generate -b=192 -o=alternate18.txt 33 | assert_command cat alternate18.txt 34 | assert_match "^([a-z]+( |$)){18}" 35 | assert_command $keysmith generate -b=224 -o=alternate21.txt 36 | assert_command cat alternate21.txt 37 | assert_match "^([a-z]+( |$)){21}" 38 | assert_command $keysmith generate -b=256 -o=alternate24.txt 39 | assert_command cat alternate24.txt 40 | assert_match "^([a-z]+( |$)){24}" 41 | } 42 | 43 | @test "Can generate the seed phrase and print it to stdout" { 44 | assert_command $keysmith generate -o=- 45 | assert_match "^([a-z]+( |$)){12}" 46 | } 47 | 48 | @test "Cannot overwrite the seed phrase" { 49 | assert_command_fail $keysmith generate 50 | assert_eq "Error: Output file already exists: seed.txt" 51 | } 52 | 53 | @test "Can derive the extended private key using input from a file" { 54 | assert_command $keysmith x-private-key 55 | assert_command cat identity.bip32 56 | assert_eq "xprv9yPcfi4GmpvHJSAq8uqytXTYCFUGJsjCRUwjwLn5CJcv4bKg9S3XGN9Y53GSUCTdtZ4UHVkmDJGH1bPkPqoFGButnUiMbZNFDBqPM9JGrmH" 57 | } 58 | 59 | @test "Can derive the extended private key using input from stdin" { 60 | assert_command bash -c "cat seed.txt | $keysmith x-private-key -f=-" 61 | assert_command cat identity.bip32 62 | assert_eq "xprv9yPcfi4GmpvHJSAq8uqytXTYCFUGJsjCRUwjwLn5CJcv4bKg9S3XGN9Y53GSUCTdtZ4UHVkmDJGH1bPkPqoFGButnUiMbZNFDBqPM9JGrmH" 63 | } 64 | 65 | @test "Can derive the extended private key using alternate input forms" { 66 | for word in $(cat seed.txt); do 67 | echo $word >> alternate.txt 68 | done 69 | assert_command $keysmith x-private-key -f=alternate.txt 70 | assert_command cat identity.bip32 71 | assert_eq "xprv9yPcfi4GmpvHJSAq8uqytXTYCFUGJsjCRUwjwLn5CJcv4bKg9S3XGN9Y53GSUCTdtZ4UHVkmDJGH1bPkPqoFGButnUiMbZNFDBqPM9JGrmH" 72 | } 73 | 74 | @test "Can derive the extended private key and print it to stdout" { 75 | assert_command $keysmith generate -o=alternate.txt 76 | assert_command $keysmith x-private-key -f=alternate.txt -o=- 77 | assert_match "^xprv[A-HJ-NP-Za-km-z1-9]" 78 | } 79 | 80 | @test "Cannot overwrite the extended private key" { 81 | assert_command $keysmith x-private-key 82 | assert_command_fail $keysmith x-private-key 83 | assert_eq "Error: Output file already exists: identity.bip32" 84 | } 85 | 86 | @test "Can derive the private key using input from a file" { 87 | assert_command $keysmith private-key 88 | assert_command cat identity.pem 89 | assert_eq "-----BEGIN EC PARAMETERS----- 90 | BgUrgQQACg== 91 | -----END EC PARAMETERS----- 92 | -----BEGIN EC PRIVATE KEY----- 93 | MHQCAQEEIAgy7nZEcVHkQ4Z1Kdqby8SwyAiyKDQmtbEHTIM+WNeBoAcGBSuBBAAK 94 | oUQDQgAEgO87rJ1ozzdMvJyZQ+GABDqUxGLvgnAnTlcInV3NuhuPv4O3VGzMGzeB 95 | N3d26cRxD99TPtm8uo2OuzKhSiq6EQ== 96 | -----END EC PRIVATE KEY-----" "$stdout" 97 | 98 | assert_command $keysmith private-key -i=0 -o=identity-0.pem 99 | assert_command cat identity-0.pem 100 | assert_eq "-----BEGIN EC PARAMETERS----- 101 | BgUrgQQACg== 102 | -----END EC PARAMETERS----- 103 | -----BEGIN EC PRIVATE KEY----- 104 | MHQCAQEEIAgy7nZEcVHkQ4Z1Kdqby8SwyAiyKDQmtbEHTIM+WNeBoAcGBSuBBAAK 105 | oUQDQgAEgO87rJ1ozzdMvJyZQ+GABDqUxGLvgnAnTlcInV3NuhuPv4O3VGzMGzeB 106 | N3d26cRxD99TPtm8uo2OuzKhSiq6EQ== 107 | -----END EC PRIVATE KEY-----" "$stdout" 108 | 109 | assert_command $keysmith private-key -i=1 -o=identity-1.pem 110 | assert_command cat identity-1.pem 111 | assert_eq "-----BEGIN EC PARAMETERS----- 112 | BgUrgQQACg== 113 | -----END EC PARAMETERS----- 114 | -----BEGIN EC PRIVATE KEY----- 115 | MHQCAQEEIE8w9tDe+X5FBMP14TBA/E3gAy/N/8BiBxQR2NB0L1B7oAcGBSuBBAAK 116 | oUQDQgAEcNM2gNSiAdbF7xf8gFK7PiNWm8DRr+hCzsFsAEFTvtZp6jypJ3f3Xhxv 117 | o9L9hwq3YMvKasyS1vxw4slTdoRUkQ== 118 | -----END EC PRIVATE KEY-----" "$stdout" 119 | 120 | assert_command $keysmith private-key -i=2 -o=identity-2.pem 121 | assert_command cat identity-2.pem 122 | assert_eq "-----BEGIN EC PARAMETERS----- 123 | BgUrgQQACg== 124 | -----END EC PARAMETERS----- 125 | -----BEGIN EC PRIVATE KEY----- 126 | MHQCAQEEIHDKbrXnyrCZpn8oLnf/Aly+GjkJvAayTYayMTmoLl9AoAcGBSuBBAAK 127 | oUQDQgAE7FiHvFu/N7Fi8MRWCsLZ0Q3dcAswvwZMEzmaHLzzZu1pG11rO5NE60Tl 128 | mKp0Tkab/fs2fifq0HmIqUrRnH5bXw== 129 | -----END EC PRIVATE KEY-----" "$stdout" 130 | 131 | assert_command $keysmith private-key -i=3 -o=identity-3.pem 132 | assert_command cat identity-3.pem 133 | assert_eq "-----BEGIN EC PARAMETERS----- 134 | BgUrgQQACg== 135 | -----END EC PARAMETERS----- 136 | -----BEGIN EC PRIVATE KEY----- 137 | MHQCAQEEIB3B3+x3S4wvAS6yyypLROVApLNmg8AFWqgWK8roc9CooAcGBSuBBAAK 138 | oUQDQgAE4p5mPhOCFsFFtGFIuQl1hr4JBopajLW9VbFlWMQs9y/h2QuTOyv5nS+y 139 | mytJ2LxkaViJHzERQUskA0Ihc6GNBQ== 140 | -----END EC PRIVATE KEY-----" "$stdout" 141 | 142 | assert_command $keysmith private-key -i=4 -o=identity-4.pem 143 | assert_command cat identity-4.pem 144 | assert_eq "-----BEGIN EC PARAMETERS----- 145 | BgUrgQQACg== 146 | -----END EC PARAMETERS----- 147 | -----BEGIN EC PRIVATE KEY----- 148 | MHQCAQEEIPHd9uF+unjyQNs5lOUVJB5K0pjwGsdi8LjR4z7Yvg+joAcGBSuBBAAK 149 | oUQDQgAEVlxWQ+Ly7lgtMXHRSg/5UQLRgT8fio3cG/stKRXTUQZ78hM3pHYvSLND 150 | G0skaaUZtGfppLY3mZNr1ZiG1cRX3A== 151 | -----END EC PRIVATE KEY-----" "$stdout" 152 | 153 | assert_command $keysmith private-key -i=5 -o=identity-5.pem 154 | assert_command cat identity-5.pem 155 | assert_eq "-----BEGIN EC PARAMETERS----- 156 | BgUrgQQACg== 157 | -----END EC PARAMETERS----- 158 | -----BEGIN EC PRIVATE KEY----- 159 | MHQCAQEEIGw7GKDWzdDTtPZWMYWTxcNsCViL6ZQ8UPqGtUFY7zYwoAcGBSuBBAAK 160 | oUQDQgAE2l9VqsOtEYPdUgNt/Zvnb4fE3Wo3FD1VMJL2rdAW591LeRRUuGQ/Kkv+ 161 | I7kZp91ZWVQPd2GrDNUXD7rSI/74Xw== 162 | -----END EC PRIVATE KEY-----" "$stdout" 163 | 164 | assert_command $keysmith private-key -i=6 -o=identity-6.pem 165 | assert_command cat identity-6.pem 166 | assert_eq "-----BEGIN EC PARAMETERS----- 167 | BgUrgQQACg== 168 | -----END EC PARAMETERS----- 169 | -----BEGIN EC PRIVATE KEY----- 170 | MHQCAQEEIPcrApGrVb3jlhPTKMh+vqEPxvLNLxP7zZzP1yar7xoNoAcGBSuBBAAK 171 | oUQDQgAEd/n6hcKJObZPzeD9bOAiZa1ZLEslqk3gSntGHdaLscX0fPSJKBBzrpQK 172 | QSp1rNZDIkRJv4UWTpugn8IG246pfw== 173 | -----END EC PRIVATE KEY-----" "$stdout" 174 | 175 | assert_command $keysmith private-key -i=7 -o=identity-7.pem 176 | assert_command cat identity-7.pem 177 | assert_eq "-----BEGIN EC PARAMETERS----- 178 | BgUrgQQACg== 179 | -----END EC PARAMETERS----- 180 | -----BEGIN EC PRIVATE KEY----- 181 | MHQCAQEEIHbt5vrScCNACRFPQrXgUDuRBTlyl7jpMq85DsQOUFL1oAcGBSuBBAAK 182 | oUQDQgAExJNfFJlg1pn+7/IcDbiN8AHYZ02qBfZT+X3Vjk6s7Ztu+4LCXFjg68cJ 183 | TiijK7kVlgFK8C24XOgK1DIXTVg7cw== 184 | -----END EC PRIVATE KEY-----" "$stdout" 185 | } 186 | 187 | @test "Can derive the private key using input from stdin" { 188 | assert_command bash -c "cat seed.txt | $keysmith private-key -f=-" 189 | assert_command cat identity.pem 190 | assert_eq "-----BEGIN EC PARAMETERS----- 191 | BgUrgQQACg== 192 | -----END EC PARAMETERS----- 193 | -----BEGIN EC PRIVATE KEY----- 194 | MHQCAQEEIAgy7nZEcVHkQ4Z1Kdqby8SwyAiyKDQmtbEHTIM+WNeBoAcGBSuBBAAK 195 | oUQDQgAEgO87rJ1ozzdMvJyZQ+GABDqUxGLvgnAnTlcInV3NuhuPv4O3VGzMGzeB 196 | N3d26cRxD99TPtm8uo2OuzKhSiq6EQ== 197 | -----END EC PRIVATE KEY-----" "$stdout" 198 | 199 | assert_command bash -c "cat seed.txt | $keysmith private-key -f=- -i=0 -o=identity-0.pem" 200 | assert_command cat identity-0.pem 201 | assert_eq "-----BEGIN EC PARAMETERS----- 202 | BgUrgQQACg== 203 | -----END EC PARAMETERS----- 204 | -----BEGIN EC PRIVATE KEY----- 205 | MHQCAQEEIAgy7nZEcVHkQ4Z1Kdqby8SwyAiyKDQmtbEHTIM+WNeBoAcGBSuBBAAK 206 | oUQDQgAEgO87rJ1ozzdMvJyZQ+GABDqUxGLvgnAnTlcInV3NuhuPv4O3VGzMGzeB 207 | N3d26cRxD99TPtm8uo2OuzKhSiq6EQ== 208 | -----END EC PRIVATE KEY-----" "$stdout" 209 | 210 | assert_command bash -c "cat seed.txt | $keysmith private-key -f=- -i=1 -o=identity-1.pem" 211 | assert_command cat identity-1.pem 212 | assert_eq "-----BEGIN EC PARAMETERS----- 213 | BgUrgQQACg== 214 | -----END EC PARAMETERS----- 215 | -----BEGIN EC PRIVATE KEY----- 216 | MHQCAQEEIE8w9tDe+X5FBMP14TBA/E3gAy/N/8BiBxQR2NB0L1B7oAcGBSuBBAAK 217 | oUQDQgAEcNM2gNSiAdbF7xf8gFK7PiNWm8DRr+hCzsFsAEFTvtZp6jypJ3f3Xhxv 218 | o9L9hwq3YMvKasyS1vxw4slTdoRUkQ== 219 | -----END EC PRIVATE KEY-----" "$stdout" 220 | 221 | assert_command bash -c "cat seed.txt | $keysmith private-key -f=- -i=2 -o=identity-2.pem" 222 | assert_command cat identity-2.pem 223 | assert_eq "-----BEGIN EC PARAMETERS----- 224 | BgUrgQQACg== 225 | -----END EC PARAMETERS----- 226 | -----BEGIN EC PRIVATE KEY----- 227 | MHQCAQEEIHDKbrXnyrCZpn8oLnf/Aly+GjkJvAayTYayMTmoLl9AoAcGBSuBBAAK 228 | oUQDQgAE7FiHvFu/N7Fi8MRWCsLZ0Q3dcAswvwZMEzmaHLzzZu1pG11rO5NE60Tl 229 | mKp0Tkab/fs2fifq0HmIqUrRnH5bXw== 230 | -----END EC PRIVATE KEY-----" "$stdout" 231 | 232 | assert_command bash -c "cat seed.txt | $keysmith private-key -f=- -i=3 -o=identity-3.pem" 233 | assert_command cat identity-3.pem 234 | assert_eq "-----BEGIN EC PARAMETERS----- 235 | BgUrgQQACg== 236 | -----END EC PARAMETERS----- 237 | -----BEGIN EC PRIVATE KEY----- 238 | MHQCAQEEIB3B3+x3S4wvAS6yyypLROVApLNmg8AFWqgWK8roc9CooAcGBSuBBAAK 239 | oUQDQgAE4p5mPhOCFsFFtGFIuQl1hr4JBopajLW9VbFlWMQs9y/h2QuTOyv5nS+y 240 | mytJ2LxkaViJHzERQUskA0Ihc6GNBQ== 241 | -----END EC PRIVATE KEY-----" "$stdout" 242 | 243 | assert_command bash -c "cat seed.txt | $keysmith private-key -f=- -i=4 -o=identity-4.pem" 244 | assert_command cat identity-4.pem 245 | assert_eq "-----BEGIN EC PARAMETERS----- 246 | BgUrgQQACg== 247 | -----END EC PARAMETERS----- 248 | -----BEGIN EC PRIVATE KEY----- 249 | MHQCAQEEIPHd9uF+unjyQNs5lOUVJB5K0pjwGsdi8LjR4z7Yvg+joAcGBSuBBAAK 250 | oUQDQgAEVlxWQ+Ly7lgtMXHRSg/5UQLRgT8fio3cG/stKRXTUQZ78hM3pHYvSLND 251 | G0skaaUZtGfppLY3mZNr1ZiG1cRX3A== 252 | -----END EC PRIVATE KEY-----" "$stdout" 253 | 254 | assert_command bash -c "cat seed.txt | $keysmith private-key -f=- -i=5 -o=identity-5.pem" 255 | assert_command cat identity-5.pem 256 | assert_eq "-----BEGIN EC PARAMETERS----- 257 | BgUrgQQACg== 258 | -----END EC PARAMETERS----- 259 | -----BEGIN EC PRIVATE KEY----- 260 | MHQCAQEEIGw7GKDWzdDTtPZWMYWTxcNsCViL6ZQ8UPqGtUFY7zYwoAcGBSuBBAAK 261 | oUQDQgAE2l9VqsOtEYPdUgNt/Zvnb4fE3Wo3FD1VMJL2rdAW591LeRRUuGQ/Kkv+ 262 | I7kZp91ZWVQPd2GrDNUXD7rSI/74Xw== 263 | -----END EC PRIVATE KEY-----" "$stdout" 264 | 265 | assert_command bash -c "cat seed.txt | $keysmith private-key -f=- -i=6 -o=identity-6.pem" 266 | assert_command cat identity-6.pem 267 | assert_eq "-----BEGIN EC PARAMETERS----- 268 | BgUrgQQACg== 269 | -----END EC PARAMETERS----- 270 | -----BEGIN EC PRIVATE KEY----- 271 | MHQCAQEEIPcrApGrVb3jlhPTKMh+vqEPxvLNLxP7zZzP1yar7xoNoAcGBSuBBAAK 272 | oUQDQgAEd/n6hcKJObZPzeD9bOAiZa1ZLEslqk3gSntGHdaLscX0fPSJKBBzrpQK 273 | QSp1rNZDIkRJv4UWTpugn8IG246pfw== 274 | -----END EC PRIVATE KEY-----" "$stdout" 275 | 276 | assert_command bash -c "cat seed.txt | $keysmith private-key -f=- -i=7 -o=identity-7.pem" 277 | assert_command cat identity-7.pem 278 | assert_eq "-----BEGIN EC PARAMETERS----- 279 | BgUrgQQACg== 280 | -----END EC PARAMETERS----- 281 | -----BEGIN EC PRIVATE KEY----- 282 | MHQCAQEEIHbt5vrScCNACRFPQrXgUDuRBTlyl7jpMq85DsQOUFL1oAcGBSuBBAAK 283 | oUQDQgAExJNfFJlg1pn+7/IcDbiN8AHYZ02qBfZT+X3Vjk6s7Ztu+4LCXFjg68cJ 284 | TiijK7kVlgFK8C24XOgK1DIXTVg7cw== 285 | -----END EC PRIVATE KEY-----" "$stdout" 286 | } 287 | 288 | @test "Can derive the private key using alternate input forms" { 289 | for word in $(cat seed.txt); do 290 | echo $word >> alternate.txt 291 | done 292 | assert_command $keysmith private-key -f=alternate.txt 293 | assert_command cat identity.pem 294 | assert_eq "-----BEGIN EC PARAMETERS----- 295 | BgUrgQQACg== 296 | -----END EC PARAMETERS----- 297 | -----BEGIN EC PRIVATE KEY----- 298 | MHQCAQEEIAgy7nZEcVHkQ4Z1Kdqby8SwyAiyKDQmtbEHTIM+WNeBoAcGBSuBBAAK 299 | oUQDQgAEgO87rJ1ozzdMvJyZQ+GABDqUxGLvgnAnTlcInV3NuhuPv4O3VGzMGzeB 300 | N3d26cRxD99TPtm8uo2OuzKhSiq6EQ== 301 | -----END EC PRIVATE KEY-----" "$stdout" 302 | } 303 | 304 | @test "Can derive the private key and print it to stdout" { 305 | assert_command $keysmith generate -o=alternate.txt 306 | assert_command $keysmith private-key -f=alternate.txt -o=- 307 | assert_match "^-----BEGIN EC PARAMETERS----- 308 | BgUrgQQACg== 309 | -----END EC PARAMETERS----- 310 | -----BEGIN EC PRIVATE KEY----- 311 | [A-Za-z0-9+/]{64} 312 | [A-Za-z0-9+/]{64} 313 | [A-Za-z0-9+/]{30}== 314 | -----END EC PRIVATE KEY-----" "$stdout" 315 | } 316 | 317 | @test "Can derive the private key and parse it with OpenSSL" { 318 | assert_command $keysmith generate -o=alternate.txt 319 | assert_command $keysmith private-key -f=alternate.txt 320 | assert_command openssl pkey -in identity.pem 321 | } 322 | 323 | @test "Cannot overwrite the private key" { 324 | assert_command $keysmith private-key 325 | assert_command_fail $keysmith private-key 326 | assert_eq "Error: Output file already exists: identity.pem" 327 | } 328 | 329 | @test "Can derive the extended public key using input from a file" { 330 | assert_command $keysmith x-public-key 331 | assert_eq "xpub6CNy5DbAcCUaWvFJEwNzFfQGkHJkiLT3nhsLjjBgke9twPepgyMmpAU1vKq4KnEqG6BeyoQx2YVjFuo5jSWjok4zCCNE8VDgSrZPYvGPkch" 332 | } 333 | 334 | @test "Can derive the extended public key using input from stdin" { 335 | assert_command bash -c "cat seed.txt | $keysmith x-public-key -f=-" 336 | assert_eq "xpub6CNy5DbAcCUaWvFJEwNzFfQGkHJkiLT3nhsLjjBgke9twPepgyMmpAU1vKq4KnEqG6BeyoQx2YVjFuo5jSWjok4zCCNE8VDgSrZPYvGPkch" 337 | } 338 | 339 | @test "Can derive the public key using input from a file" { 340 | assert_command $keysmith public-key 341 | assert_eq "0480ef3bac9d68cf374cbc9c9943e180043a94c462ef8270274e57089d5dcdba1b8fbf83b7546ccc1b3781377776e9c4710fdf533ed9bcba8d8ebb32a14a2aba11" 342 | assert_command $keysmith public-key -i=0 343 | assert_eq "0480ef3bac9d68cf374cbc9c9943e180043a94c462ef8270274e57089d5dcdba1b8fbf83b7546ccc1b3781377776e9c4710fdf533ed9bcba8d8ebb32a14a2aba11" 344 | assert_command $keysmith public-key -i=1 345 | assert_eq "0470d33680d4a201d6c5ef17fc8052bb3e23569bc0d1afe842cec16c004153bed669ea3ca92777f75e1c6fa3d2fd870ab760cbca6acc92d6fc70e2c95376845491" 346 | assert_command $keysmith public-key -i=2 347 | assert_eq "04ec5887bc5bbf37b162f0c4560ac2d9d10ddd700b30bf064c13399a1cbcf366ed691b5d6b3b9344eb44e598aa744e469bfdfb367e27ead07988a94ad19c7e5b5f" 348 | assert_command $keysmith public-key -i=3 349 | assert_eq "04e29e663e138216c145b46148b9097586be09068a5a8cb5bd55b16558c42cf72fe1d90b933b2bf99d2fb29b2b49d8bc646958891f3111414b2403422173a18d05" 350 | assert_command $keysmith public-key -i=4 351 | assert_eq "04565c5643e2f2ee582d3171d14a0ff95102d1813f1f8a8ddc1bfb2d2915d351067bf21337a4762f48b3431b4b2469a519b467e9a4b63799936bd59886d5c457dc" 352 | assert_command $keysmith public-key -i=5 353 | assert_eq "04da5f55aac3ad1183dd52036dfd9be76f87c4dd6a37143d553092f6add016e7dd4b791454b8643f2a4bfe23b919a7dd5959540f7761ab0cd5170fbad223fef85f" 354 | assert_command $keysmith public-key -i=6 355 | assert_eq "0477f9fa85c28939b64fcde0fd6ce02265ad592c4b25aa4de04a7b461dd68bb1c5f47cf489281073ae940a412a75acd643224449bf85164e9ba09fc206db8ea97f" 356 | assert_command $keysmith public-key -i=7 357 | assert_eq "04c4935f149960d699feeff21c0db88df001d8674daa05f653f97dd58e4eaced9b6efb82c25c58e0ebc7094e28a32bb91596014af02db85ce80ad432174d583b73" 358 | } 359 | 360 | @test "Can derive the public key using input from stdin" { 361 | assert_command bash -c "cat seed.txt | $keysmith public-key -f=-" 362 | assert_eq "0480ef3bac9d68cf374cbc9c9943e180043a94c462ef8270274e57089d5dcdba1b8fbf83b7546ccc1b3781377776e9c4710fdf533ed9bcba8d8ebb32a14a2aba11" 363 | assert_command bash -c "cat seed.txt | $keysmith public-key -f=- -i=0" 364 | assert_eq "0480ef3bac9d68cf374cbc9c9943e180043a94c462ef8270274e57089d5dcdba1b8fbf83b7546ccc1b3781377776e9c4710fdf533ed9bcba8d8ebb32a14a2aba11" 365 | assert_command bash -c "cat seed.txt | $keysmith public-key -f=- -i=1" 366 | assert_eq "0470d33680d4a201d6c5ef17fc8052bb3e23569bc0d1afe842cec16c004153bed669ea3ca92777f75e1c6fa3d2fd870ab760cbca6acc92d6fc70e2c95376845491" 367 | assert_command bash -c "cat seed.txt | $keysmith public-key -f=- -i=2" 368 | assert_eq "04ec5887bc5bbf37b162f0c4560ac2d9d10ddd700b30bf064c13399a1cbcf366ed691b5d6b3b9344eb44e598aa744e469bfdfb367e27ead07988a94ad19c7e5b5f" 369 | assert_command bash -c "cat seed.txt | $keysmith public-key -f=- -i=3" 370 | assert_eq "04e29e663e138216c145b46148b9097586be09068a5a8cb5bd55b16558c42cf72fe1d90b933b2bf99d2fb29b2b49d8bc646958891f3111414b2403422173a18d05" 371 | assert_command bash -c "cat seed.txt | $keysmith public-key -f=- -i=4" 372 | assert_eq "04565c5643e2f2ee582d3171d14a0ff95102d1813f1f8a8ddc1bfb2d2915d351067bf21337a4762f48b3431b4b2469a519b467e9a4b63799936bd59886d5c457dc" 373 | assert_command bash -c "cat seed.txt | $keysmith public-key -f=- -i=5" 374 | assert_eq "04da5f55aac3ad1183dd52036dfd9be76f87c4dd6a37143d553092f6add016e7dd4b791454b8643f2a4bfe23b919a7dd5959540f7761ab0cd5170fbad223fef85f" 375 | assert_command bash -c "cat seed.txt | $keysmith public-key -f=- -i=6" 376 | assert_eq "0477f9fa85c28939b64fcde0fd6ce02265ad592c4b25aa4de04a7b461dd68bb1c5f47cf489281073ae940a412a75acd643224449bf85164e9ba09fc206db8ea97f" 377 | assert_command bash -c "cat seed.txt | $keysmith public-key -f=- -i=7" 378 | assert_eq "04c4935f149960d699feeff21c0db88df001d8674daa05f653f97dd58e4eaced9b6efb82c25c58e0ebc7094e28a32bb91596014af02db85ce80ad432174d583b73" 379 | } 380 | 381 | @test "Can derive the legacy address using input from a file" { 382 | assert_command $keysmith legacy-address 383 | assert_eq "abde4f2523cc796bfd63564124b1c9b577c183b3" 384 | assert_command $keysmith legacy-address -i=0 385 | assert_eq "abde4f2523cc796bfd63564124b1c9b577c183b3" 386 | assert_command $keysmith legacy-address -i=1 387 | assert_eq "0b98ad668da5702f2d127c8de01cbd0de3ed5ce8" 388 | assert_command $keysmith legacy-address -i=2 389 | assert_eq "a5ebdb7665b68446328e8356c1808db3fc068d93" 390 | assert_command $keysmith legacy-address -i=3 391 | assert_eq "50a7bc9a4d205a8ce96e6c1bd3a6543f6acb19b4" 392 | assert_command $keysmith legacy-address -i=4 393 | assert_eq "985f1a72ebf6580770d9047d78823e8be5777a39" 394 | assert_command $keysmith legacy-address -i=5 395 | assert_eq "6c22e8745c81b5cffcc0b12383d3668623c40172" 396 | assert_command $keysmith legacy-address -i=6 397 | assert_eq "465111daace75b765d2df70619787e0f5bec2e82" 398 | assert_command $keysmith legacy-address -i=7 399 | assert_eq "db6de8140a50b31ed18494e93b03cfe5ba082d23" 400 | } 401 | 402 | @test "Can derive the legacy address using input from stdin" { 403 | assert_command bash -c "cat seed.txt | $keysmith legacy-address -f=-" 404 | assert_eq "abde4f2523cc796bfd63564124b1c9b577c183b3" 405 | assert_command bash -c "cat seed.txt | $keysmith legacy-address -f=- -i=0" 406 | assert_eq "abde4f2523cc796bfd63564124b1c9b577c183b3" 407 | assert_command bash -c "cat seed.txt | $keysmith legacy-address -f=- -i=1" 408 | assert_eq "0b98ad668da5702f2d127c8de01cbd0de3ed5ce8" 409 | assert_command bash -c "cat seed.txt | $keysmith legacy-address -f=- -i=2" 410 | assert_eq "a5ebdb7665b68446328e8356c1808db3fc068d93" 411 | assert_command bash -c "cat seed.txt | $keysmith legacy-address -f=- -i=3" 412 | assert_eq "50a7bc9a4d205a8ce96e6c1bd3a6543f6acb19b4" 413 | assert_command bash -c "cat seed.txt | $keysmith legacy-address -f=- -i=4" 414 | assert_eq "985f1a72ebf6580770d9047d78823e8be5777a39" 415 | assert_command bash -c "cat seed.txt | $keysmith legacy-address -f=- -i=5" 416 | assert_eq "6c22e8745c81b5cffcc0b12383d3668623c40172" 417 | assert_command bash -c "cat seed.txt | $keysmith legacy-address -f=- -i=6" 418 | assert_eq "465111daace75b765d2df70619787e0f5bec2e82" 419 | assert_command bash -c "cat seed.txt | $keysmith legacy-address -f=- -i=7" 420 | assert_eq "db6de8140a50b31ed18494e93b03cfe5ba082d23" 421 | } 422 | 423 | @test "Can derive the principal using input from a file" { 424 | assert_command $keysmith principal 425 | assert_eq "t2kpu-6xt6l-tyb3d-rll2p-irv5c-no5nd-h6spj-jsetq-bmqdz-iap77-pqe" 426 | assert_command $keysmith principal -i=0 427 | assert_eq "t2kpu-6xt6l-tyb3d-rll2p-irv5c-no5nd-h6spj-jsetq-bmqdz-iap77-pqe" 428 | assert_command $keysmith principal -i=1 429 | assert_eq "ncpzz-qv6a2-ult3n-4mmvz-gdrhx-ileg4-upz7f-7zfqi-affpy-zlkid-hae" 430 | assert_command $keysmith principal -i=2 431 | assert_eq "oz7pj-bab4p-7iyos-7f3be-i565q-xib6s-pee2u-5l6wx-fexwx-ecv3e-fae" 432 | assert_command $keysmith principal -i=3 433 | assert_eq "xxdyl-bobgu-u3q5w-r67od-b2tc3-mkyv3-m4hlt-5psfn-6rkxt-eyv4x-kae" 434 | assert_command $keysmith principal -i=4 435 | assert_eq "tbl5g-hjbsu-wkhvn-djwco-uztju-cate7-g4p5b-bvqxa-5bg6a-yb6s3-wqe" 436 | assert_command $keysmith principal -i=5 437 | assert_eq "yksvc-462au-rmv5f-w6jlz-7h7ts-pkob5-adhrm-aj7gb-dwylz-3t53y-uae" 438 | assert_command $keysmith principal -i=6 439 | assert_eq "nhiqy-qh3xw-v2s6h-mkwpc-7kmo6-ue3i5-qpjk3-mqfmv-dnvox-hux72-5ae" 440 | assert_command $keysmith principal -i=7 441 | assert_eq "7dm5n-v2brn-p2mla-3t5cw-ppdog-ro5fo-4psh3-zotg2-ix6or-26au2-iae" 442 | } 443 | 444 | @test "Can derive the principal using input from stdin" { 445 | assert_command bash -c "cat seed.txt | $keysmith principal -f=-" 446 | assert_eq "t2kpu-6xt6l-tyb3d-rll2p-irv5c-no5nd-h6spj-jsetq-bmqdz-iap77-pqe" 447 | assert_command bash -c "cat seed.txt | $keysmith principal -f=- -i=0" 448 | assert_eq "t2kpu-6xt6l-tyb3d-rll2p-irv5c-no5nd-h6spj-jsetq-bmqdz-iap77-pqe" 449 | assert_command bash -c "cat seed.txt | $keysmith principal -f=- -i=1" 450 | assert_eq "ncpzz-qv6a2-ult3n-4mmvz-gdrhx-ileg4-upz7f-7zfqi-affpy-zlkid-hae" 451 | assert_command bash -c "cat seed.txt | $keysmith principal -f=- -i=2" 452 | assert_eq "oz7pj-bab4p-7iyos-7f3be-i565q-xib6s-pee2u-5l6wx-fexwx-ecv3e-fae" 453 | assert_command bash -c "cat seed.txt | $keysmith principal -f=- -i=3" 454 | assert_eq "xxdyl-bobgu-u3q5w-r67od-b2tc3-mkyv3-m4hlt-5psfn-6rkxt-eyv4x-kae" 455 | assert_command bash -c "cat seed.txt | $keysmith principal -f=- -i=4" 456 | assert_eq "tbl5g-hjbsu-wkhvn-djwco-uztju-cate7-g4p5b-bvqxa-5bg6a-yb6s3-wqe" 457 | assert_command bash -c "cat seed.txt | $keysmith principal -f=- -i=5" 458 | assert_eq "yksvc-462au-rmv5f-w6jlz-7h7ts-pkob5-adhrm-aj7gb-dwylz-3t53y-uae" 459 | assert_command bash -c "cat seed.txt | $keysmith principal -f=- -i=6" 460 | assert_eq "nhiqy-qh3xw-v2s6h-mkwpc-7kmo6-ue3i5-qpjk3-mqfmv-dnvox-hux72-5ae" 461 | assert_command bash -c "cat seed.txt | $keysmith principal -f=- -i=7" 462 | assert_eq "7dm5n-v2brn-p2mla-3t5cw-ppdog-ro5fo-4psh3-zotg2-ix6or-26au2-iae" 463 | } 464 | 465 | @test "Can derive the account using input from a file" { 466 | assert_command $keysmith account 467 | assert_eq "53a3ef3b11b69c6411cd1667970e24577c857acf3cdd67436656c75d4ddd3cc7" 468 | assert_command $keysmith account -i=0 469 | assert_eq "53a3ef3b11b69c6411cd1667970e24577c857acf3cdd67436656c75d4ddd3cc7" 470 | assert_command $keysmith account -i=1 471 | assert_eq "6bf62b34a4eeb32721aeb99fe598d760ca252a0324155fc8b0ef203f3fc620cc" 472 | assert_command $keysmith account -i=2 473 | assert_eq "2f1a51eadb26c0dcee782a8069018abdcce2c60a386ad9c0351ac4328d7346d8" 474 | assert_command $keysmith account -i=3 475 | assert_eq "927e01c4b46c7f4d3363c9823de9af067eb0f3e13e7b4cdb455bedbe7268bf0e" 476 | assert_command $keysmith account -i=4 477 | assert_eq "2b84c97f17ea887eb0374d14db1402867879a163c4799583327bd38afeb93d51" 478 | assert_command $keysmith account -i=5 479 | assert_eq "e29bf07177868d4c43b08857eb47dd99991aafafa918290e7a2561deab054aa1" 480 | assert_command $keysmith account -i=6 481 | assert_eq "9fed555b071f02563c0b24a3a70f5b2a1a863b97b80717da70e4816d1edc47e0" 482 | assert_command $keysmith account -i=7 483 | assert_eq "91e6f4b6bb528d8a26288cbc677407e09fb19493a567aaae7589ac0b1d03f9dc" 484 | } 485 | 486 | @test "Can derive the account using input from stdin" { 487 | assert_command bash -c "cat seed.txt | $keysmith account -f=-" 488 | assert_eq "53a3ef3b11b69c6411cd1667970e24577c857acf3cdd67436656c75d4ddd3cc7" 489 | assert_command bash -c "cat seed.txt | $keysmith account -f=- -i=0" 490 | assert_eq "53a3ef3b11b69c6411cd1667970e24577c857acf3cdd67436656c75d4ddd3cc7" 491 | assert_command bash -c "cat seed.txt | $keysmith account -f=- -i=1" 492 | assert_eq "6bf62b34a4eeb32721aeb99fe598d760ca252a0324155fc8b0ef203f3fc620cc" 493 | assert_command bash -c "cat seed.txt | $keysmith account -f=- -i=2" 494 | assert_eq "2f1a51eadb26c0dcee782a8069018abdcce2c60a386ad9c0351ac4328d7346d8" 495 | assert_command bash -c "cat seed.txt | $keysmith account -f=- -i=3" 496 | assert_eq "927e01c4b46c7f4d3363c9823de9af067eb0f3e13e7b4cdb455bedbe7268bf0e" 497 | assert_command bash -c "cat seed.txt | $keysmith account -f=- -i=4" 498 | assert_eq "2b84c97f17ea887eb0374d14db1402867879a163c4799583327bd38afeb93d51" 499 | assert_command bash -c "cat seed.txt | $keysmith account -f=- -i=5" 500 | assert_eq "e29bf07177868d4c43b08857eb47dd99991aafafa918290e7a2561deab054aa1" 501 | assert_command bash -c "cat seed.txt | $keysmith account -f=- -i=6" 502 | assert_eq "9fed555b071f02563c0b24a3a70f5b2a1a863b97b80717da70e4816d1edc47e0" 503 | assert_command bash -c "cat seed.txt | $keysmith account -f=- -i=7" 504 | assert_eq "91e6f4b6bb528d8a26288cbc677407e09fb19493a567aaae7589ac0b1d03f9dc" 505 | } 506 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= 5 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 6 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 7 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 8 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 9 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 10 | cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= 11 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 12 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 13 | cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= 14 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 15 | cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 16 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 17 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 18 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 19 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 20 | collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= 21 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 22 | github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= 23 | github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= 24 | github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= 25 | github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= 26 | github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= 27 | github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= 28 | github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= 29 | github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= 30 | github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= 31 | github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= 32 | github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= 33 | github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= 34 | github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= 35 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 36 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 37 | github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= 38 | github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 39 | github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= 40 | github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= 41 | github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw= 42 | github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= 43 | github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= 44 | github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= 45 | github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= 46 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 47 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 48 | github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= 49 | github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= 50 | github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= 51 | github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= 52 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= 53 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= 54 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 55 | github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 56 | github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= 57 | github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= 58 | github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= 59 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= 60 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= 61 | github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= 62 | github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= 63 | github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= 64 | github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= 65 | github.com/axw/gocov v1.0.0/go.mod h1:LvQpEYiwwIb2nYkXY2fDWhg9/AsYqkhmrCshjlUJECE= 66 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 67 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 68 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 69 | github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= 70 | github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= 71 | github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= 72 | github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= 73 | github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= 74 | github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= 75 | github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= 76 | github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= 77 | github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= 78 | github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= 79 | github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= 80 | github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= 81 | github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= 82 | github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= 83 | github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= 84 | github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= 85 | github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= 86 | github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= 87 | github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= 88 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 89 | github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= 90 | github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= 91 | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= 92 | github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= 93 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 94 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 95 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 96 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 97 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 98 | github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= 99 | github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= 100 | github.com/consensys/bavard v0.1.8-0.20210105233146-c16790d2aa8b/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= 101 | github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= 102 | github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= 103 | github.com/consensys/goff v0.3.10/go.mod h1:xTldOBEHmFiYS0gPXd3NsaEqZWlnmeWcRLWgD3ba3xc= 104 | github.com/consensys/gurvy v0.3.8/go.mod h1:sN75xnsiD593XnhbhvG2PkOy194pZBzqShWF/kwuW/g= 105 | github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= 106 | github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= 107 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 108 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 109 | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 110 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 111 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 112 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 113 | github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= 114 | github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= 115 | github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 116 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 117 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 118 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 119 | github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= 120 | github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= 121 | github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= 122 | github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= 123 | github.com/dfinity/go-hdkeychain v1.1.0 h1:V5W9dAuLm7kjd2dQUX97K69Zll6mvu4YdoEehOeq4Ss= 124 | github.com/dfinity/go-hdkeychain v1.1.0/go.mod h1:IPus/bqkSN52PvJpQvVdmPyhenDb5xvbvcDaXy7/BCk= 125 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 126 | github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= 127 | github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= 128 | github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= 129 | github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= 130 | github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= 131 | github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= 132 | github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= 133 | github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= 134 | github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= 135 | github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= 136 | github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= 137 | github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= 138 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 139 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 140 | github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= 141 | github.com/ethereum/go-ethereum v1.10.0 h1:EBZuZYjk1DHboBJb2YkBN8xItELRY6mtZEiYJKuH0+M= 142 | github.com/ethereum/go-ethereum v1.10.0/go.mod h1:E5e/zvdfUVr91JZ0AwjyuJM3x+no51zZJRz61orLLSk= 143 | github.com/ethereum/go-ethereum v1.10.12 h1:el/KddB3gLEsnNgGQ3SQuZuiZjwnFTYHe5TwUet5Om4= 144 | github.com/ethereum/go-ethereum v1.10.12/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw= 145 | github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 146 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 147 | github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= 148 | github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= 149 | github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 150 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 151 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 152 | github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= 153 | github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= 154 | github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= 155 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 156 | github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= 157 | github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= 158 | github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= 159 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 160 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 161 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 162 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 163 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 164 | github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= 165 | github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= 166 | github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 167 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 168 | github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= 169 | github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= 170 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 171 | github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= 172 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 173 | github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= 174 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 175 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 176 | github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 177 | github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= 178 | github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= 179 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 180 | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 181 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 182 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 183 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 184 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 185 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 186 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 187 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 188 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 189 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 190 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 191 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 192 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 193 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 194 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 195 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 196 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 197 | github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 198 | github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3 h1:ur2rms48b3Ep1dxh7aUV2FZEQ8jEVO2F6ILKx8ofkAg= 199 | github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 200 | github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 201 | github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 202 | github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= 203 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 204 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 205 | github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 206 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 207 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 208 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 209 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 210 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 211 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 212 | github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 213 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 214 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 215 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 216 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 217 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 218 | github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 219 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 220 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 221 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 222 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 223 | github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= 224 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 225 | github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= 226 | github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= 227 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= 228 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= 229 | github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= 230 | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= 231 | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 232 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 233 | github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= 234 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 235 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 236 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 237 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 238 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= 239 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 240 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= 241 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 242 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 243 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= 244 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 245 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 246 | github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= 247 | github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= 248 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 249 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 250 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= 251 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= 252 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= 253 | github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= 254 | github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= 255 | github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= 256 | github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= 257 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 258 | github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= 259 | github.com/huin/goupnp v1.0.1-0.20200620063722-49508fba0031/go.mod h1:nNs7wvRfN1eKaMknBydLNQU6146XQim8t4h+q90biWo= 260 | github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= 261 | github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= 262 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 263 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 264 | github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= 265 | github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= 266 | github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= 267 | github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= 268 | github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= 269 | github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= 270 | github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= 271 | github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= 272 | github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= 273 | github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= 274 | github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= 275 | github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= 276 | github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= 277 | github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= 278 | github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 279 | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 280 | github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= 281 | github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= 282 | github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= 283 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 284 | github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= 285 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 286 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 287 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 288 | github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= 289 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 290 | github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 291 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 292 | github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= 293 | github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= 294 | github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= 295 | github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= 296 | github.com/kilic/bls12-381 v0.0.0-20201226121925-69dacb279461/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= 297 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 298 | github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 299 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 300 | github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= 301 | github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 302 | github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= 303 | github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= 304 | github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= 305 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 306 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 307 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 308 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 309 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 310 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 311 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 312 | github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= 313 | github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= 314 | github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= 315 | github.com/leanovate/gopter v0.2.8/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8= 316 | github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= 317 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 318 | github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 319 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 320 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 321 | github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= 322 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 323 | github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 324 | github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 325 | github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 326 | github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 327 | github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= 328 | github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= 329 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 330 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 331 | github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 332 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 333 | github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= 334 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 335 | github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 336 | github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= 337 | github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 338 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 339 | github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 340 | github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= 341 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 342 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 343 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= 344 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 345 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 346 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= 347 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= 348 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= 349 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 350 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 351 | github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 352 | github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= 353 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 354 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 355 | github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= 356 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 357 | github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= 358 | github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= 359 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 360 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= 361 | github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= 362 | github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c h1:1RHs3tNxjXGHeul8z2t6H2N2TlAqpKe5yryJztRx4Jk= 363 | github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= 364 | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 365 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 366 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 367 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 368 | github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= 369 | github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 370 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 371 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 372 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 373 | github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= 374 | github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= 375 | github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= 376 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 377 | github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= 378 | github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= 379 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 380 | github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= 381 | github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= 382 | github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= 383 | github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 384 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 385 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 386 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 387 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 388 | github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= 389 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 390 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 391 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 392 | github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= 393 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= 394 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 395 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 396 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 397 | github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 398 | github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 399 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 400 | github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= 401 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 402 | github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 403 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 404 | github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= 405 | github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= 406 | github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= 407 | github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= 408 | github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= 409 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 410 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 411 | github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= 412 | github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= 413 | github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= 414 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 415 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= 416 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 417 | github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= 418 | github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= 419 | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 420 | github.com/shirou/gopsutil v2.20.5+incompatible h1:tYH07UPoQt0OCQdgWWMgYHy3/a9bcxNpBIysykNIP7I= 421 | github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 422 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 423 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 424 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 425 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 426 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 427 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= 428 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 429 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 430 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 431 | github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= 432 | github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= 433 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 434 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 435 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 436 | github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= 437 | github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= 438 | github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= 439 | github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= 440 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 441 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 442 | github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 443 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 444 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 445 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 446 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 447 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 448 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= 449 | github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= 450 | github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= 451 | github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= 452 | github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= 453 | github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= 454 | github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= 455 | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= 456 | github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= 457 | github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= 458 | github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= 459 | github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= 460 | github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= 461 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 462 | github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= 463 | github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= 464 | github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= 465 | github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= 466 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= 467 | github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= 468 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 469 | go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= 470 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 471 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 472 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 473 | go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 474 | go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 475 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= 476 | go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 477 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 478 | golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 479 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 480 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 481 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 482 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 483 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 484 | golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 485 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 486 | golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 487 | golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 488 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= 489 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 490 | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 491 | golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= 492 | golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= 493 | golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 494 | golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 495 | golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 496 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 497 | golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 498 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 499 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 500 | golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= 501 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 502 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 503 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 504 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 505 | golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= 506 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 507 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 508 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 509 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 510 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 511 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 512 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 513 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 514 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 515 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 516 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 517 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 518 | golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= 519 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 520 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 521 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 522 | golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 523 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 524 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 525 | golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 526 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 527 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 528 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 529 | golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 530 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 531 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 532 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 533 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 534 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 535 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 536 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 537 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 538 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 539 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 540 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 541 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 542 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 543 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 544 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 545 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 546 | golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 547 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 548 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 549 | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 550 | golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 551 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 552 | golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 553 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 554 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 555 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 556 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 557 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 558 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 559 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 560 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 561 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 562 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 563 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 564 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 565 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 566 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 567 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 568 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 569 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 570 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 571 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 572 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 573 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 574 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 575 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 576 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 577 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 578 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 579 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 580 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 581 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 582 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 583 | golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 584 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 585 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 586 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 587 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 588 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 589 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 590 | golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 591 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 592 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 593 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 594 | golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 595 | golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 596 | golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 597 | golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 598 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 599 | golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 600 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 601 | golang.org/x/sys v0.0.0-20210105210732-16f7687f5001/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 602 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 603 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= 604 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 605 | golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 606 | golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 607 | golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 608 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 609 | golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 h1:uCLL3g5wH2xjxVREVuAbP9JM5PPKjRbXKRa6IBjkzmU= 610 | golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 611 | golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 612 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 613 | golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= 614 | golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 615 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 616 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 617 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 618 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 619 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 620 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 621 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 622 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 623 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 624 | golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 625 | golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 626 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 627 | golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 628 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 629 | golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 630 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 631 | golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 632 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 633 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 634 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 635 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 636 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 637 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 638 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 639 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 640 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 641 | golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 642 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 643 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 644 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 645 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 646 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 647 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 648 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 649 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 650 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 651 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 652 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 653 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 654 | golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 655 | golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 656 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 657 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 658 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 659 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 660 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 661 | gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= 662 | gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= 663 | gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= 664 | gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= 665 | gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= 666 | gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= 667 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 668 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 669 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 670 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 671 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 672 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 673 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 674 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 675 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 676 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 677 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 678 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 679 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 680 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 681 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 682 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 683 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 684 | google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 685 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 686 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 687 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 688 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 689 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 690 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 691 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 692 | google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 693 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 694 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 695 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 696 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 697 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 698 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 699 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 700 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 701 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 702 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 703 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 704 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 705 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 706 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 707 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 708 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 709 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 710 | gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 711 | gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= 712 | gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= 713 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 714 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 715 | gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= 716 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= 717 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 718 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 719 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 720 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 721 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 722 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 723 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 724 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 725 | gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= 726 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 727 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 728 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 729 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 730 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 731 | honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= 732 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 733 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 734 | --------------------------------------------------------------------------------