├── .dockerignore ├── .github └── workflows │ ├── docker.yml │ ├── golangci-lint.yml │ ├── release.yml │ └── test.yml ├── .gitignore ├── .golangci.yml ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── beacon ├── chaininfo.go └── validatorinfo.go ├── cmd ├── account.go ├── account │ ├── create │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ └── run.go │ ├── derive │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── import │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ └── key │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── accountcreate.go ├── accountderive.go ├── accountimport.go ├── accountinfo.go ├── accountkey.go ├── accountlock.go ├── accountunlock.go ├── attestation.go ├── attester.go ├── attester │ ├── duties │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ └── inclusion │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── attesterduties.go ├── attesterinclusion.go ├── block.go ├── block │ ├── analyze │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── info │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ └── trail │ │ ├── command.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── blockanalyze.go ├── blockinfo.go ├── blocktrail.go ├── chain.go ├── chain │ ├── eth1votes │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── queues │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── time │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ └── verify │ │ └── signedcontributionandproof │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── chaineth1votes.go ├── chaininfo.go ├── chainqueues.go ├── chainspec.go ├── chainstatus.go ├── chaintime.go ├── chainverify.go ├── chainverifysignedcontributionandproof.go ├── constants.go ├── deposit.go ├── depositverify.go ├── epoch.go ├── epoch │ └── summary │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── epochsummary.go ├── err.go ├── exit.go ├── exitverify.go ├── node.go ├── node │ └── events │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── nodeevents.go ├── nodeinfo.go ├── passphrases.go ├── proposer.go ├── proposer │ └── duties │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── proposerduties.go ├── root.go ├── signature.go ├── signatureaggregate.go ├── signaturesign.go ├── signatureverify.go ├── slot.go ├── slot │ └── time │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── slottime.go ├── synccommittee.go ├── synccommittee │ ├── inclusion │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ └── members │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── synccommitteeinclusion.go ├── synccommitteemembers.go ├── validator.go ├── validator │ ├── credentials │ │ ├── get │ │ │ ├── command.go │ │ │ ├── command_internal_test.go │ │ │ ├── output.go │ │ │ ├── process.go │ │ │ └── run.go │ │ └── set │ │ │ ├── chaininfo.go │ │ │ ├── command.go │ │ │ ├── command_internal_test.go │ │ │ ├── output.go │ │ │ ├── process.go │ │ │ ├── process_internal_test.go │ │ │ └── run.go │ ├── depositdata │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── duties │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── exit │ │ ├── chaininfo.go │ │ ├── command.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── expectation │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── keycheck │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ └── run.go │ ├── summary │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── withdrawal │ │ ├── command.go │ │ ├── output.go │ │ ├── process.go │ │ └── run.go │ └── yield │ │ ├── command.go │ │ ├── command_internal_test.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── validatorcredentials.go ├── validatorcredentialsget.go ├── validatorcredentialsset.go ├── validatordepositdata.go ├── validatorduties.go ├── validatorexit.go ├── validatorexpectation.go ├── validatorinfo.go ├── validatorkeycheck.go ├── validatorsummary.go ├── validatorwithdrawal.go ├── validatoryield.go ├── version.go ├── wallet.go ├── wallet │ ├── batch │ │ ├── command.go │ │ ├── output.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── create │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── delete │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── export │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── import │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ ├── sharedexport │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go │ └── sharedimport │ │ ├── input.go │ │ ├── input_internal_test.go │ │ ├── output.go │ │ ├── output_internal_test.go │ │ ├── process.go │ │ ├── process_internal_test.go │ │ └── run.go ├── walletaccounts.go ├── walletbatch.go ├── walletcreate.go ├── walletdelete.go ├── walletexport.go ├── walletimport.go ├── walletinfo.go ├── walletlist.go ├── walletsharedexport.go └── walletsharedimport.go ├── docs ├── changingwithdrawalcredentials.md ├── conversions.md ├── exitingvalidators.md ├── howto.md ├── images │ ├── credentials-change-offline.png │ ├── credentials-change-online.png │ ├── diagrams.svg │ ├── exit-offline.png │ └── exit-online.png ├── troubleshooting.md └── usage.md ├── go.mod ├── go.sum ├── main.go ├── services └── chaintime │ ├── service.go │ └── standard │ ├── parameters.go │ ├── service.go │ └── service_test.go ├── shamir ├── shamir.go ├── shamir_test.go ├── tables.go └── tables_test.go ├── signing ├── container.go ├── container_encoding.go ├── generate.go ├── misc.go └── signroot.go ├── testutil └── bytes.go └── util ├── account.go ├── account_test.go ├── attestations.go ├── basedir.go ├── basedir_test.go ├── beaconheadercache.go ├── beaconnode.go ├── bls.go ├── bls_test.go ├── depositinfo.go ├── depositinfo_internal_test.go ├── depositinfo_test.go ├── epoch.go ├── epoch_test.go ├── logging.go ├── logging_internal_test.go ├── misc.go ├── mnemonic.go ├── mnemonic_test.go ├── networks.go ├── networks_internal_test.go ├── networks_test.go ├── passphrase.go ├── passphrase_test.go ├── passphrases.go ├── passphrases_test.go ├── scratchaccount.go ├── scratchaccount_test.go ├── signing.go ├── slot.go ├── slot_test.go ├── validator.go ├── validatorexitdata.go ├── validatorexitdata_test.go └── validators.go /.dockerignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | ethdo 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | coverage.html 14 | 15 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 16 | .glide/ 17 | 18 | # Vim 19 | *.sw? 20 | 21 | # Local TODO 22 | TODO.md 23 | 24 | Dockerfile -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Docker 2 | 3 | on: 4 | push: 5 | 6 | jobs: 7 | # Set variables that will be available to all builds. 8 | env_vars: 9 | runs-on: ubuntu-latest 10 | outputs: 11 | release_version: ${{ steps.release_version.outputs.release_version }} 12 | binary: ${{ steps.binary.outputs.binary }} 13 | steps: 14 | - id: release_version 15 | run: | 16 | RELEASE_VERSION=$(echo ${{ github.ref_name }} | sed -e 's/^[vt]//') 17 | echo "release_version=${RELEASE_VERSION}" >> $GITHUB_OUTPUT 18 | - id: binary 19 | run: | 20 | BINARY=$(basename ${{ github.repository }}) 21 | echo "binary=${BINARY}" >> $GITHUB_OUTPUT 22 | 23 | # Build. 24 | build: 25 | runs-on: ubuntu-latest 26 | needs: [env_vars] 27 | steps: 28 | - name: Check out repository into the Go module directory 29 | uses: actions/checkout@v3 30 | 31 | - name: Set up QEMU 32 | uses: docker/setup-qemu-action@v2 33 | 34 | - name: Set up Docker Buildx 35 | uses: docker/setup-buildx-action@v2 36 | 37 | - name: Login to Docker Hub 38 | uses: docker/login-action@v2 39 | with: 40 | username: ${{ secrets.DOCKERHUB_USERNAME }} 41 | password: ${{ secrets.DOCKERHUB_TOKEN }} 42 | 43 | - name: Build and push 44 | uses: docker/build-push-action@v4 45 | with: 46 | context: . 47 | platforms: linux/amd64,linux/arm64/v8 48 | push: true 49 | tags: wealdtech/ethdo:latest 50 | 51 | - name: build and push on release 52 | uses: docker/build-push-action@v4 53 | if: ${{ github.event.release.tag_name != '' }} 54 | with: 55 | context: . 56 | platforms: linux/amd64,linux/arm64/v8 57 | push: true 58 | tags: wealdtech/ethdo:${{ github.event.release.tag_name }} 59 | -------------------------------------------------------------------------------- /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | name: 'golangci-lint' 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - 'master' 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: 'read' 11 | pull-requests: 'read' 12 | checks: 'write' 13 | 14 | jobs: 15 | golangci: 16 | name: 'lint' 17 | runs-on: 'ubuntu-24.04' 18 | steps: 19 | - uses: 'actions/setup-go@v5' 20 | with: 21 | cache: false 22 | go-version: '^1.22' 23 | - uses: 'actions/checkout@v4' 24 | - uses: 'golangci/golangci-lint-action@v6' 25 | with: 26 | version: 'latest' 27 | args: '--timeout=60m' 28 | only-new-issues: true 29 | skip-cache: true 30 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/setup-go@v5 14 | with: 15 | cache: false 16 | go-version: '^1.22' 17 | - uses: actions/checkout@v4 18 | - uses: n8maninger/action-golang-test@v2 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | ethdo 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | coverage.html 14 | 15 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 16 | .glide/ 17 | 18 | # Intellij 19 | .idea/ 20 | 21 | # Makefile 22 | Makefile 23 | 24 | # Vim 25 | *.sw? 26 | 27 | # Local JSON files 28 | *.json 29 | 30 | # Local TODO 31 | TODO.md 32 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23-bookworm AS builder 2 | 3 | WORKDIR /app 4 | 5 | COPY go.mod go.sum ./ 6 | 7 | RUN go mod download 8 | 9 | COPY . . 10 | 11 | RUN go build 12 | 13 | FROM debian:bookworm-slim 14 | 15 | RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt install -y ca-certificates && apt-get clean && rm -rf /var/lib/apt/lists/* 16 | 17 | WORKDIR /app 18 | 19 | COPY --from=builder /app/ethdo /app 20 | 21 | ENTRYPOINT ["/app/ethdo"] 22 | -------------------------------------------------------------------------------- /cmd/account.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // accountCmd represents the account command. 21 | var accountCmd = &cobra.Command{ 22 | Use: "account", 23 | Short: "Manage account", 24 | Long: `Create and view accounts.`, 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(accountCmd) 29 | } 30 | 31 | func accountFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/account/create/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountcreate 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | 20 | "github.com/pkg/errors" 21 | e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2" 22 | ) 23 | 24 | type dataOut struct { 25 | account e2wtypes.Account 26 | } 27 | 28 | func output(_ context.Context, data *dataOut) (string, error) { 29 | if data == nil { 30 | return "", errors.New("no data") 31 | } 32 | if data.account == nil { 33 | return "", errors.New("no account") 34 | } 35 | 36 | if pubKeyProvider, ok := data.account.(e2wtypes.AccountCompositePublicKeyProvider); ok { 37 | return fmt.Sprintf("%#x", pubKeyProvider.CompositePublicKey().Marshal()), nil 38 | } 39 | 40 | if pubKeyProvider, ok := data.account.(e2wtypes.AccountPublicKeyProvider); ok { 41 | return fmt.Sprintf("%#x", pubKeyProvider.PublicKey().Marshal()), nil 42 | } 43 | 44 | return "", errors.New("no public key available") 45 | } 46 | -------------------------------------------------------------------------------- /cmd/account/create/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountcreate 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the account create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if !viper.GetBool("verbose") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/account/derive/input.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020, 2023 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountderive 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/pkg/errors" 20 | "github.com/spf13/viper" 21 | ) 22 | 23 | type dataIn struct { 24 | quiet bool 25 | json bool 26 | // Derivation information. 27 | mnemonic string 28 | path string 29 | // Output options. 30 | showPrivateKey bool 31 | showWithdrawalCredentials bool 32 | generateKeystore bool 33 | } 34 | 35 | func input(_ context.Context) (*dataIn, error) { 36 | data := &dataIn{} 37 | 38 | // Quiet. 39 | data.quiet = viper.GetBool("quiet") 40 | 41 | // JSON. 42 | data.json = viper.GetBool("json") 43 | 44 | // Mnemonic. 45 | if viper.GetString("mnemonic") == "" { 46 | return nil, errors.New("mnemonic is required") 47 | } 48 | data.mnemonic = viper.GetString("mnemonic") 49 | 50 | // Path. 51 | if viper.GetString("path") == "" { 52 | return nil, errors.New("path is required") 53 | } 54 | data.path = viper.GetString("path") 55 | 56 | // Show private key. 57 | data.showPrivateKey = viper.GetBool("show-private-key") 58 | 59 | // Show withdrawal credentials. 60 | data.showWithdrawalCredentials = viper.GetBool("show-withdrawal-credentials") 61 | 62 | // Generate keystore. 63 | data.generateKeystore = viper.GetBool("generate-keystore") 64 | 65 | return data, nil 66 | } 67 | -------------------------------------------------------------------------------- /cmd/account/derive/process.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020, 2023 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountderive 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/pkg/errors" 20 | "github.com/wealdtech/ethdo/util" 21 | e2types "github.com/wealdtech/go-eth2-types/v2" 22 | e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2" 23 | ) 24 | 25 | func process(ctx context.Context, data *dataIn) (*dataOut, error) { 26 | if data == nil { 27 | return nil, errors.New("no data") 28 | } 29 | 30 | account, err := util.ParseAccount(ctx, data.mnemonic, []string{data.path}, true) 31 | if err != nil { 32 | return nil, errors.Wrap(err, "failed to derive account") 33 | } 34 | 35 | key, err := account.(e2wtypes.AccountPrivateKeyProvider).PrivateKey(ctx) 36 | if err != nil { 37 | return nil, errors.Wrap(err, "failed to obtain account private key") 38 | } 39 | 40 | results := &dataOut{ 41 | json: data.json, 42 | showPrivateKey: data.showPrivateKey, 43 | showWithdrawalCredentials: data.showWithdrawalCredentials, 44 | generateKeystore: data.generateKeystore, 45 | key: key.(*e2types.BLSPrivateKey), 46 | path: data.path, 47 | } 48 | 49 | return results, nil 50 | } 51 | -------------------------------------------------------------------------------- /cmd/account/derive/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountderive 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | "strings" 20 | 21 | "github.com/spf13/cobra" 22 | ) 23 | 24 | // Run runs the account create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to obtain input"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if dataIn.quiet { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return strings.TrimSuffix(results, "\n"), nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/account/import/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountimport 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | 20 | "github.com/pkg/errors" 21 | e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2" 22 | ) 23 | 24 | type dataOut struct { 25 | account e2wtypes.Account 26 | } 27 | 28 | func output(_ context.Context, data *dataOut) (string, error) { 29 | if data == nil { 30 | return "", errors.New("no data") 31 | } 32 | if data.account == nil { 33 | return "", errors.New("no account") 34 | } 35 | 36 | if pubKeyProvider, ok := data.account.(e2wtypes.AccountCompositePublicKeyProvider); ok { 37 | return fmt.Sprintf("%#x", pubKeyProvider.CompositePublicKey().Marshal()), nil 38 | } 39 | 40 | if pubKeyProvider, ok := data.account.(e2wtypes.AccountPublicKeyProvider); ok { 41 | return fmt.Sprintf("%#x", pubKeyProvider.PublicKey().Marshal()), nil 42 | } 43 | 44 | return "", errors.New("no public key available") 45 | } 46 | -------------------------------------------------------------------------------- /cmd/account/import/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountimport 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the account import data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to obtain input"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if !viper.GetBool("verbose") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/account/key/input.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountkey 15 | 16 | import ( 17 | "context" 18 | "time" 19 | 20 | "github.com/pkg/errors" 21 | "github.com/spf13/viper" 22 | "github.com/wealdtech/ethdo/util" 23 | e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2" 24 | ) 25 | 26 | type dataIn struct { 27 | timeout time.Duration 28 | account e2wtypes.Account 29 | passphrases []string 30 | } 31 | 32 | func input(ctx context.Context) (*dataIn, error) { 33 | var err error 34 | data := &dataIn{} 35 | 36 | if viper.GetDuration("timeout") == 0 { 37 | return nil, errors.New("timeout is required") 38 | } 39 | data.timeout = viper.GetDuration("timeout") 40 | 41 | // Account. 42 | _, data.account, err = util.WalletAndAccountFromInput(ctx) 43 | if err != nil { 44 | return nil, errors.Wrap(err, "failed to obtain acount") 45 | } 46 | 47 | // Passphrases. 48 | data.passphrases = util.GetPassphrases() 49 | 50 | return data, nil 51 | } 52 | -------------------------------------------------------------------------------- /cmd/account/key/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountkey 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | 20 | "github.com/pkg/errors" 21 | ) 22 | 23 | type dataOut struct { 24 | key []byte 25 | } 26 | 27 | func output(_ context.Context, data *dataOut) (string, error) { 28 | if data == nil { 29 | return "", errors.New("no data") 30 | } 31 | if len(data.key) == 0 { 32 | return "", errors.New("no account") 33 | } 34 | 35 | return fmt.Sprintf("%#x", data.key), nil 36 | } 37 | -------------------------------------------------------------------------------- /cmd/account/key/output_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountkey 15 | 16 | import ( 17 | "context" 18 | "encoding/hex" 19 | "strings" 20 | "testing" 21 | 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func hexToBytes(input string) []byte { 26 | res, err := hex.DecodeString(strings.TrimPrefix(input, "0x")) 27 | if err != nil { 28 | panic(err) 29 | } 30 | return res 31 | } 32 | 33 | func TestOutput(t *testing.T) { 34 | tests := []struct { 35 | name string 36 | dataOut *dataOut 37 | res string 38 | err string 39 | }{ 40 | { 41 | name: "Nil", 42 | err: "no data", 43 | }, 44 | { 45 | name: "AccountNil", 46 | dataOut: &dataOut{}, 47 | err: "no account", 48 | }, 49 | { 50 | name: "Good", 51 | dataOut: &dataOut{ 52 | key: hexToBytes("0x25295f0d1d592a90b333e26e85149708208e9f8e8bc18f6c77bd62f8ad7a6866"), 53 | }, 54 | res: "0x25295f0d1d592a90b333e26e85149708208e9f8e8bc18f6c77bd62f8ad7a6866", 55 | }, 56 | } 57 | 58 | for _, test := range tests { 59 | t.Run(test.name, func(t *testing.T) { 60 | res, err := output(context.Background(), test.dataOut) 61 | if test.err != "" { 62 | require.EqualError(t, err, test.err) 63 | } else { 64 | require.NoError(t, err) 65 | require.Equal(t, test.res, res) 66 | } 67 | }) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /cmd/account/key/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package accountkey 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the account import data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/accountkey.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2017-2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | "github.com/spf13/viper" 21 | accountkey "github.com/wealdtech/ethdo/cmd/account/key" 22 | ) 23 | 24 | // accountKeyCmd represents the account key command. 25 | var accountKeyCmd = &cobra.Command{ 26 | Use: "key", 27 | Short: "Obtain the private key of an account.", 28 | Long: `Obtain the private key of an account. For example: 29 | 30 | ethdo account key --account="Personal wallet/Operations" --passphrase="my account passphrase" 31 | 32 | In quiet mode this will return 0 if the key can be obtained, otherwise 1.`, 33 | RunE: func(cmd *cobra.Command, _ []string) error { 34 | res, err := accountkey.Run(cmd) 35 | if err != nil { 36 | return err 37 | } 38 | if viper.GetBool("quiet") { 39 | return nil 40 | } 41 | if res != "" { 42 | fmt.Println(res) 43 | } 44 | return nil 45 | }, 46 | } 47 | 48 | func init() { 49 | accountCmd.AddCommand(accountKeyCmd) 50 | accountFlags(accountKeyCmd) 51 | } 52 | -------------------------------------------------------------------------------- /cmd/accountlock.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/spf13/cobra" 20 | "github.com/spf13/viper" 21 | e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2" 22 | ) 23 | 24 | var accountLockCmd = &cobra.Command{ 25 | Use: "lock", 26 | Short: "Lock a remote account", 27 | Long: `Lock a remote account. For example: 28 | 29 | ethdo account lock --account="primary/my funds" 30 | 31 | In quiet mode this will return 0 if the account is locked, otherwise 1.`, 32 | Run: func(_ *cobra.Command, _ []string) { 33 | ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout")) 34 | defer cancel() 35 | 36 | assert(viper.GetString("account") != "", "--account is required") 37 | 38 | _, account, err := walletAndAccountFromInput(ctx) 39 | errCheck(err, "Failed to obtain account") 40 | 41 | locker, isLocker := account.(e2wtypes.AccountLocker) 42 | assert(isLocker, "Account does not support locking") 43 | 44 | err = locker.Lock(ctx) 45 | errCheck(err, "Failed to lock account") 46 | }, 47 | } 48 | 49 | func init() { 50 | accountCmd.AddCommand(accountLockCmd) 51 | accountFlags(accountLockCmd) 52 | } 53 | -------------------------------------------------------------------------------- /cmd/attestation.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // attestationCmd represents the attestation command. 21 | var attestationCmd = &cobra.Command{ 22 | Use: "attestation", 23 | Short: "Obtain information about an Ethereum 2 attestation", 24 | Long: "Obtain information about an Ethereum 2 attestation", 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(attestationCmd) 29 | } 30 | -------------------------------------------------------------------------------- /cmd/attester.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // attesterCmd represents the attester command. 21 | var attesterCmd = &cobra.Command{ 22 | Use: "attester", 23 | Short: "Obtain information about Ethereum 2 attesters", 24 | Long: "Obtain information about Ethereum 2 attesters", 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(attesterCmd) 29 | } 30 | 31 | func attesterFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/attester/duties/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package attesterduties 15 | 16 | import ( 17 | "context" 18 | "encoding/json" 19 | "fmt" 20 | 21 | api "github.com/attestantio/go-eth2-client/api/v1" 22 | "github.com/pkg/errors" 23 | ) 24 | 25 | type dataOut struct { 26 | debug bool 27 | quiet bool 28 | verbose bool 29 | json bool 30 | duty *api.AttesterDuty 31 | } 32 | 33 | func output(_ context.Context, data *dataOut) (string, error) { 34 | if data == nil { 35 | return "", errors.New("no data") 36 | } 37 | 38 | if data.quiet { 39 | return "", nil 40 | } 41 | 42 | if data.duty == nil { 43 | return "No duties found", nil 44 | } 45 | 46 | if data.json { 47 | bytes, err := json.Marshal(data.duty) 48 | if err != nil { 49 | return "", errors.Wrap(err, "failed to marshalJSON") 50 | } 51 | return string(bytes), nil 52 | } 53 | 54 | return fmt.Sprintf("Validator attesting in slot %d committee %d", data.duty.Slot, data.duty.CommitteeIndex), nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/attester/duties/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package attesterduties 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/attester/inclusion/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package attesterinclusion 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/block.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // blockCmd represents the block command. 21 | var blockCmd = &cobra.Command{ 22 | Use: "block", 23 | Short: "Obtain information about an Ethereum 2 block", 24 | Long: "Obtain information about an Ethereum 2 block", 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(blockCmd) 29 | } 30 | 31 | func blockFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/block/analyze/command_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package blockanalyze 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestInput(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "TimeoutMissing", 37 | vars: map[string]interface{}{}, 38 | err: "timeout is required", 39 | }, 40 | { 41 | name: "Good", 42 | vars: map[string]interface{}{ 43 | "blockid": "1", 44 | "timeout": "5s", 45 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 46 | }, 47 | }, 48 | } 49 | 50 | for _, test := range tests { 51 | t.Run(test.name, func(t *testing.T) { 52 | viper.Reset() 53 | 54 | for k, v := range test.vars { 55 | viper.Set(k, v) 56 | } 57 | _, err := newCommand(context.Background()) 58 | if test.err != "" { 59 | require.EqualError(t, err, test.err) 60 | } else { 61 | require.NoError(t, err) 62 | } 63 | }) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /cmd/block/analyze/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package blockanalyze 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/block/info/process_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2023 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package blockinfo 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/attestantio/go-eth2-client/auto" 22 | "github.com/rs/zerolog" 23 | "github.com/stretchr/testify/require" 24 | ) 25 | 26 | func TestProcess(t *testing.T) { 27 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 28 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 29 | } 30 | eth2Client, err := auto.New(context.Background(), 31 | auto.WithLogLevel(zerolog.Disabled), 32 | auto.WithAddress(os.Getenv("ETHDO_TEST_CONNECTION")), 33 | ) 34 | require.NoError(t, err) 35 | 36 | tests := []struct { 37 | name string 38 | dataIn *dataIn 39 | err string 40 | }{ 41 | { 42 | name: "Nil", 43 | err: "no data", 44 | }, 45 | { 46 | name: "NoBlockID", 47 | dataIn: &dataIn{ 48 | eth2Client: eth2Client, 49 | }, 50 | err: "no block ID", 51 | }, 52 | } 53 | 54 | for _, test := range tests { 55 | t.Run(test.name, func(t *testing.T) { 56 | _, err := process(context.Background(), test.dataIn) 57 | if test.err != "" { 58 | require.EqualError(t, err, test.err) 59 | } else { 60 | require.NoError(t, err) 61 | } 62 | }) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /cmd/block/info/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package blockinfo 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/block/trail/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2025 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package blocktrail 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | "os" 20 | 21 | "github.com/spf13/cobra" 22 | "github.com/spf13/viper" 23 | ) 24 | 25 | // Run runs the command. 26 | func Run(cmd *cobra.Command) (string, error) { 27 | ctx := context.Background() 28 | 29 | c, err := newCommand(ctx) 30 | if err != nil { 31 | return "", errors.Join(errors.New("failed to set up command"), err) 32 | } 33 | 34 | // Further errors do not need a usage report. 35 | cmd.SilenceUsage = true 36 | 37 | if err := c.process(ctx); err != nil { 38 | switch { 39 | case errors.Is(err, context.DeadlineExceeded): 40 | return "", errors.New("operation timed out; try increasing with --timeout option") 41 | default: 42 | return "", errors.Join(errors.New("failed to process"), err) 43 | } 44 | } 45 | 46 | if viper.GetBool("quiet") { 47 | if c.found { 48 | return "", nil 49 | } 50 | os.Exit(1) 51 | } 52 | 53 | results, err := c.output(ctx) 54 | if err != nil { 55 | return "", errors.Join(errors.New("failed to obtain output"), err) 56 | } 57 | 58 | return results, nil 59 | } 60 | -------------------------------------------------------------------------------- /cmd/chain.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // chainCmd represents the chain command. 21 | var chainCmd = &cobra.Command{ 22 | Use: "chain", 23 | Short: "Obtain information about an Ethereum 2 chain", 24 | Long: "Obtain information about an Ethereum 2 chain", 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(chainCmd) 29 | } 30 | 31 | func chainFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/chain/eth1votes/command_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package chaineth1votes 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestInput(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "TimeoutMissing", 37 | vars: map[string]interface{}{}, 38 | err: "timeout is required", 39 | }, 40 | { 41 | name: "Good", 42 | vars: map[string]interface{}{ 43 | "timeout": "5s", 44 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 45 | }, 46 | }, 47 | } 48 | 49 | for _, test := range tests { 50 | t.Run(test.name, func(t *testing.T) { 51 | viper.Reset() 52 | 53 | for k, v := range test.vars { 54 | viper.Set(k, v) 55 | } 56 | _, err := newCommand(context.Background()) 57 | if test.err != "" { 58 | require.EqualError(t, err, test.err) 59 | } else { 60 | require.NoError(t, err) 61 | } 62 | }) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /cmd/chain/eth1votes/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package chaineth1votes 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/chain/queues/command_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package chainqueues 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestInput(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "TimeoutMissing", 37 | vars: map[string]interface{}{}, 38 | err: "timeout is required", 39 | }, 40 | { 41 | name: "Good", 42 | vars: map[string]interface{}{ 43 | "timeout": "5s", 44 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 45 | }, 46 | }, 47 | } 48 | 49 | for _, test := range tests { 50 | t.Run(test.name, func(t *testing.T) { 51 | viper.Reset() 52 | 53 | for k, v := range test.vars { 54 | viper.Set(k, v) 55 | } 56 | _, err := newCommand(context.Background()) 57 | if test.err != "" { 58 | require.EqualError(t, err, test.err) 59 | } else { 60 | require.NoError(t, err) 61 | } 62 | }) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /cmd/chain/queues/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package chainqueues 15 | 16 | import ( 17 | "context" 18 | "encoding/json" 19 | "fmt" 20 | "strings" 21 | ) 22 | 23 | type jsonOutput struct { 24 | ActivationQueue int `json:"activation_queue"` 25 | ExitQueue int `json:"exit_queue"` 26 | } 27 | 28 | func (c *command) output(ctx context.Context) (string, error) { 29 | if c.quiet { 30 | return "", nil 31 | } 32 | 33 | if c.json { 34 | return c.outputJSON(ctx) 35 | } 36 | return c.outputText(ctx) 37 | } 38 | 39 | func (c *command) outputJSON(_ context.Context) (string, error) { 40 | output := &jsonOutput{ 41 | ActivationQueue: c.activationQueue, 42 | ExitQueue: c.exitQueue, 43 | } 44 | data, err := json.Marshal(output) 45 | if err != nil { 46 | return "", err 47 | } 48 | 49 | return string(data), nil 50 | } 51 | 52 | func (c *command) outputText(_ context.Context) (string, error) { 53 | builder := strings.Builder{} 54 | 55 | if c.activationQueue > 0 { 56 | builder.WriteString(fmt.Sprintf("Activation queue: %d\n", c.activationQueue)) 57 | } 58 | if c.exitQueue > 0 { 59 | builder.WriteString(fmt.Sprintf("Exit queue: %d\n", c.exitQueue)) 60 | } 61 | 62 | return strings.TrimSuffix(builder.String(), "\n"), nil 63 | } 64 | -------------------------------------------------------------------------------- /cmd/chain/queues/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package chainqueues 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/chain/time/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package chaintime 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/chain/verify/signedcontributionandproof/process_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package chainverifysignedcontributionandproof 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestProcess(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "InvalidData", 37 | vars: map[string]interface{}{ 38 | "timeout": "5s", 39 | "data": "[[", 40 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 41 | }, 42 | }, 43 | } 44 | 45 | for _, test := range tests { 46 | t.Run(test.name, func(t *testing.T) { 47 | viper.Reset() 48 | 49 | for k, v := range test.vars { 50 | viper.Set(k, v) 51 | } 52 | cmd, err := newCommand(context.Background()) 53 | require.NoError(t, err) 54 | err = cmd.process(context.Background()) 55 | if test.err != "" { 56 | require.EqualError(t, err, test.err) 57 | } else { 58 | require.NoError(t, err) 59 | } 60 | }) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /cmd/chain/verify/signedcontributionandproof/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package chainverifysignedcontributionandproof 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/chainqueues.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | "github.com/spf13/viper" 21 | chainqueues "github.com/wealdtech/ethdo/cmd/chain/queues" 22 | ) 23 | 24 | var chainQueuesCmd = &cobra.Command{ 25 | Use: "queues", 26 | Short: "Show chain queues", 27 | Long: `Show beacon chain activation and exit queues. For example: 28 | 29 | ethdo chain queues 30 | 31 | In quiet mode this will return 0 if the entry and exit queues are 0, otherwise 1.`, 32 | RunE: func(cmd *cobra.Command, _ []string) error { 33 | res, err := chainqueues.Run(cmd) 34 | if err != nil { 35 | return err 36 | } 37 | if viper.GetBool("quiet") { 38 | return nil 39 | } 40 | if res != "" { 41 | fmt.Println(res) 42 | } 43 | return nil 44 | }, 45 | } 46 | 47 | func init() { 48 | chainCmd.AddCommand(chainQueuesCmd) 49 | chainFlags(chainQueuesCmd) 50 | chainQueuesCmd.Flags().String("epoch", "", "epoch for which to fetch the queues") 51 | } 52 | 53 | func chainQueuesBindings(cmd *cobra.Command) { 54 | if err := viper.BindPFlag("epoch", cmd.Flags().Lookup("epoch")); err != nil { 55 | panic(err) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /cmd/chainverify.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | "github.com/spf13/viper" 19 | ) 20 | 21 | // chainVerifyCmd represents the chain verify command. 22 | var chainVerifyCmd = &cobra.Command{ 23 | Use: "verify", 24 | Short: "Verify a beacon chain signature", 25 | Long: "Verify the signature for a given beacon chain structure is correct", 26 | } 27 | 28 | func init() { 29 | chainCmd.AddCommand(chainVerifyCmd) 30 | } 31 | 32 | func chainVerifyFlags(cmd *cobra.Command) { 33 | chainFlags(cmd) 34 | cmd.Flags().String("validator", "", "The account, public key or index of the validator") 35 | cmd.Flags().String("data", "", "The data to verify, as a JSON structure") 36 | } 37 | 38 | func chainVerifyBindings(cmd *cobra.Command) { 39 | if err := viper.BindPFlag("validator", cmd.Flags().Lookup("validator")); err != nil { 40 | panic(err) 41 | } 42 | if err := viper.BindPFlag("data", cmd.Flags().Lookup("data")); err != nil { 43 | panic(err) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /cmd/chainverifysignedcontributionandproof.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | chainverifysignedcontributionandproof "github.com/wealdtech/ethdo/cmd/chain/verify/signedcontributionandproof" 21 | ) 22 | 23 | var chainVerifySignedContributionAndProofCmd = &cobra.Command{ 24 | Use: "signedcontributionandproof", 25 | Short: "Verify a signed contribution and proof", 26 | Long: `Verify a signed contribution and proof. For example: 27 | 28 | ethdo chain verify signedcontributionandproof --data=... --validator=... 29 | 30 | validator can be an account, a public key or an index.`, 31 | RunE: func(cmd *cobra.Command, _ []string) error { 32 | res, err := chainverifysignedcontributionandproof.Run(cmd) 33 | if err != nil { 34 | return err 35 | } 36 | if res != "" { 37 | fmt.Print(res) 38 | } 39 | return nil 40 | }, 41 | } 42 | 43 | func init() { 44 | chainVerifyCmd.AddCommand(chainVerifySignedContributionAndProofCmd) 45 | chainVerifyFlags(chainVerifySignedContributionAndProofCmd) 46 | } 47 | 48 | func chainVerifySignedContributionAndProofBindings(cmd *cobra.Command) { 49 | chainVerifyBindings(cmd) 50 | } 51 | -------------------------------------------------------------------------------- /cmd/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | const ( 17 | _exitSuccess = 0 18 | _exitFailure = 1 19 | ) 20 | -------------------------------------------------------------------------------- /cmd/deposit.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // depositCmd represents the deposit command. 21 | var depositCmd = &cobra.Command{ 22 | Use: "deposit", 23 | Short: "Manage Ethereum 2 deposits", 24 | Long: `Manage Ethereum 2 deposits.`, 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(depositCmd) 29 | } 30 | 31 | func depositFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/epoch.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | "github.com/spf13/viper" 19 | ) 20 | 21 | // epochCmd represents the epoch command. 22 | var epochCmd = &cobra.Command{ 23 | Use: "epoch", 24 | Short: "Obtain information about Ethereum 2 epochs", 25 | Long: "Obtain information about Ethereum 2 epochs", 26 | } 27 | 28 | func init() { 29 | RootCmd.AddCommand(epochCmd) 30 | } 31 | 32 | func epochFlags(cmd *cobra.Command) { 33 | cmd.Flags().String("epoch", "", "the epoch for which to obtain information (default current, can be 'current', 'last' or a number)") 34 | } 35 | 36 | func epochBindings(cmd *cobra.Command) { 37 | if err := viper.BindPFlag("epoch", cmd.Flags().Lookup("epoch")); err != nil { 38 | panic(err) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cmd/epoch/summary/command_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package epochsummary 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestInput(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "TimeoutMissing", 37 | vars: map[string]interface{}{}, 38 | err: "timeout is required", 39 | }, 40 | { 41 | name: "Good", 42 | vars: map[string]interface{}{ 43 | "timeout": "5s", 44 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 45 | }, 46 | }, 47 | } 48 | 49 | for _, test := range tests { 50 | t.Run(test.name, func(t *testing.T) { 51 | viper.Reset() 52 | 53 | for k, v := range test.vars { 54 | viper.Set(k, v) 55 | } 56 | _, err := newCommand(context.Background()) 57 | if test.err != "" { 58 | require.EqualError(t, err, test.err) 59 | } else { 60 | require.NoError(t, err) 61 | } 62 | }) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /cmd/epoch/summary/process_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package epochsummary 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestProcess(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "InvalidData", 37 | vars: map[string]interface{}{ 38 | "timeout": "60s", 39 | "data": "[[", 40 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 41 | }, 42 | }, 43 | } 44 | 45 | for _, test := range tests { 46 | t.Run(test.name, func(t *testing.T) { 47 | viper.Reset() 48 | 49 | for k, v := range test.vars { 50 | viper.Set(k, v) 51 | } 52 | cmd, err := newCommand(context.Background()) 53 | require.NoError(t, err) 54 | err = cmd.process(context.Background()) 55 | if test.err != "" { 56 | require.EqualError(t, err, test.err) 57 | } else { 58 | require.NoError(t, err) 59 | } 60 | }) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /cmd/epoch/summary/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package epochsummary 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/epochsummary.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | "github.com/spf13/viper" 21 | epochsummary "github.com/wealdtech/ethdo/cmd/epoch/summary" 22 | ) 23 | 24 | var epochSummaryCmd = &cobra.Command{ 25 | Use: "summary", 26 | Short: "Obtain summary information about an epoch", 27 | Long: `Obtain summary information about an epoch. For example: 28 | 29 | ethdo epoch summary --epoch=12345 30 | 31 | In quiet mode this will return 0 if information for the epoch is found, otherwise 1.`, 32 | RunE: func(cmd *cobra.Command, _ []string) error { 33 | res, err := epochsummary.Run(cmd) 34 | if err != nil { 35 | return err 36 | } 37 | if viper.GetBool("quiet") { 38 | return nil 39 | } 40 | if res != "" { 41 | fmt.Println(res) 42 | } 43 | return nil 44 | }, 45 | } 46 | 47 | func init() { 48 | epochCmd.AddCommand(epochSummaryCmd) 49 | epochSummaryFlags(epochSummaryCmd) 50 | } 51 | 52 | func epochSummaryFlags(cmd *cobra.Command) { 53 | epochFlags(cmd) 54 | cmd.Flags().StringSlice("validators", nil, "the validators for which to obtain a summary") 55 | } 56 | 57 | func epochSummaryBindings(cmd *cobra.Command) { 58 | epochBindings(cmd) 59 | if err := viper.BindPFlag("validators", cmd.Flags().Lookup("validators")); err != nil { 60 | panic(err) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /cmd/exit.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // exitCmd represents the exit command. 21 | var exitCmd = &cobra.Command{ 22 | Use: "exit", 23 | Short: "Manage Ethereum 2 voluntary exits", 24 | Long: `Manage Ethereum 2 voluntary exits.`, 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(exitCmd) 29 | } 30 | 31 | func exitFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/node.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // nodeCmd represents the node command. 21 | var nodeCmd = &cobra.Command{ 22 | Use: "node", 23 | Short: "Obtain information about an Ethereum 2 node", 24 | Long: "Obtain information about an Ethereum 2 node", 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(nodeCmd) 29 | } 30 | 31 | func nodeFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/node/events/process.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package nodeevents 15 | 16 | import ( 17 | "context" 18 | "encoding/json" 19 | "fmt" 20 | 21 | eth2client "github.com/attestantio/go-eth2-client" 22 | "github.com/attestantio/go-eth2-client/api" 23 | apiv1 "github.com/attestantio/go-eth2-client/api/v1" 24 | "github.com/pkg/errors" 25 | ) 26 | 27 | func process(ctx context.Context, data *dataIn) error { 28 | if data == nil { 29 | return errors.New("no data") 30 | } 31 | 32 | err := data.eth2Client.(eth2client.EventsProvider).Events(ctx, &api.EventsOpts{ 33 | Topics: data.topics, 34 | Handler: eventHandler, 35 | }) 36 | if err != nil { 37 | return errors.Wrap(err, "failed to connect for events") 38 | } 39 | 40 | <-ctx.Done() 41 | 42 | return nil 43 | } 44 | 45 | func eventHandler(event *apiv1.Event) { 46 | if event.Data == nil { 47 | return 48 | } 49 | 50 | data, err := json.Marshal(event) 51 | if err == nil { 52 | fmt.Println(string(data)) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /cmd/node/events/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package nodeevents 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | ) 22 | 23 | // Run runs the wallet create data command. 24 | func Run(cmd *cobra.Command) (string, error) { 25 | ctx := context.Background() 26 | dataIn, err := input(ctx) 27 | if err != nil { 28 | return "", errors.Join(errors.New("failed to set up command"), err) 29 | } 30 | 31 | // Further errors do not need a usage report. 32 | cmd.SilenceUsage = true 33 | 34 | if err := process(ctx, dataIn); err != nil { 35 | switch { 36 | case errors.Is(err, context.DeadlineExceeded): 37 | return "", errors.New("operation timed out; try increasing with --timeout option") 38 | default: 39 | return "", errors.Join(errors.New("failed to process"), err) 40 | } 41 | } 42 | 43 | // Process generates all output. 44 | 45 | return "", nil 46 | } 47 | -------------------------------------------------------------------------------- /cmd/nodeevents.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | "github.com/spf13/viper" 21 | nodeevents "github.com/wealdtech/ethdo/cmd/node/events" 22 | ) 23 | 24 | var nodeEventsCmd = &cobra.Command{ 25 | Use: "events", 26 | Short: "Report events from a node", 27 | Long: `Report events from a node. For example: 28 | 29 | ethdo node events --events=head,chain_reorg.`, 30 | RunE: func(cmd *cobra.Command, _ []string) error { 31 | res, err := nodeevents.Run(cmd) 32 | if err != nil { 33 | return err 34 | } 35 | if res != "" { 36 | fmt.Println(res) 37 | } 38 | return nil 39 | }, 40 | } 41 | 42 | func init() { 43 | nodeCmd.AddCommand(nodeEventsCmd) 44 | nodeFlags(nodeEventsCmd) 45 | nodeEventsCmd.Flags().StringSlice("topics", nil, "The topics of events for which to listen (attestation,block,chain_reorg,finalized_checkpoint,head,voluntary_exit)") 46 | } 47 | 48 | func nodeEventsBindings(cmd *cobra.Command) { 49 | if err := viper.BindPFlag("topics", cmd.Flags().Lookup("topics")); err != nil { 50 | panic(err) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /cmd/passphrases.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/viper" 18 | ) 19 | 20 | // getWalletPassphrases() fetches the wallet passphrase supplied by the user. 21 | func getWalletPassphrase() string { 22 | return viper.GetString("wallet-passphrase") 23 | } 24 | 25 | // getPassphrases() fetches the passphrases supplied by the user. 26 | func getPassphrases() []string { 27 | return viper.GetStringSlice("passphrase") 28 | } 29 | -------------------------------------------------------------------------------- /cmd/proposer.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // proposerCmd represents the proposer command. 21 | var proposerCmd = &cobra.Command{ 22 | Use: "proposer", 23 | Short: "Obtain information about Ethereum 2 proposers", 24 | Long: "Obtain information about Ethereum 2 proposers", 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(proposerCmd) 29 | } 30 | 31 | func proposerFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/proposer/duties/process_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package proposerduties 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestProcess(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "InvalidData", 37 | vars: map[string]interface{}{ 38 | "timeout": "60s", 39 | "data": "[[", 40 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 41 | }, 42 | }, 43 | } 44 | 45 | for _, test := range tests { 46 | t.Run(test.name, func(t *testing.T) { 47 | viper.Reset() 48 | 49 | for k, v := range test.vars { 50 | viper.Set(k, v) 51 | } 52 | cmd, err := newCommand(context.Background()) 53 | require.NoError(t, err) 54 | err = cmd.process(context.Background()) 55 | if test.err != "" { 56 | require.EqualError(t, err, test.err) 57 | } else { 58 | require.NoError(t, err) 59 | } 60 | }) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /cmd/proposer/duties/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package proposerduties 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/signature.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | "github.com/spf13/pflag" 19 | "github.com/spf13/viper" 20 | ) 21 | 22 | // signatureCmd represents the signature command. 23 | var signatureCmd = &cobra.Command{ 24 | Use: "signature", 25 | Aliases: []string{"sig"}, 26 | Short: "Manage signatures", 27 | Long: `Sign data and verify signatures.`, 28 | } 29 | 30 | func init() { 31 | RootCmd.AddCommand(signatureCmd) 32 | } 33 | 34 | var ( 35 | dataFlag *pflag.Flag 36 | domainFlag *pflag.Flag 37 | ) 38 | 39 | func signatureFlags(cmd *cobra.Command) { 40 | if dataFlag == nil { 41 | cmd.Flags().String("data", "", "the data, as a hex string") 42 | dataFlag = cmd.Flags().Lookup("data") 43 | if err := viper.BindPFlag("signature-data", dataFlag); err != nil { 44 | panic(err) 45 | } 46 | cmd.Flags().String("domain", "0x0000000000000000000000000000000000000000000000000000000000000000", "the BLS domain, as a hex string") 47 | domainFlag = cmd.Flags().Lookup("domain") 48 | if err := viper.BindPFlag("signature-domain", domainFlag); err != nil { 49 | panic(err) 50 | } 51 | } else { 52 | cmd.Flags().AddFlag(dataFlag) 53 | cmd.Flags().AddFlag(domainFlag) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /cmd/slot.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // slotCmd represents the slot command. 21 | var slotCmd = &cobra.Command{ 22 | Use: "slot", 23 | Short: "Obtain information about an Ethereum 2 slot", 24 | Long: "Obtain information about an Ethereum 2 slot", 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(slotCmd) 29 | } 30 | 31 | func slotFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/slot/time/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package slottime 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | "time" 20 | 21 | "github.com/pkg/errors" 22 | ) 23 | 24 | type dataOut struct { 25 | debug bool 26 | quiet bool 27 | verbose bool 28 | startTime time.Time 29 | endTime time.Time 30 | } 31 | 32 | func output(_ context.Context, data *dataOut) (string, error) { 33 | if data == nil { 34 | return "", errors.New("no data") 35 | } 36 | 37 | if data.quiet { 38 | return "", nil 39 | } 40 | if data.verbose { 41 | return fmt.Sprintf("%s - %s", data.startTime, data.endTime), nil 42 | } 43 | return data.startTime.String(), nil 44 | } 45 | -------------------------------------------------------------------------------- /cmd/slot/time/output_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package slottime 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | "time" 20 | 21 | "github.com/stretchr/testify/require" 22 | ) 23 | 24 | func TestOutput(t *testing.T) { 25 | tests := []struct { 26 | name string 27 | dataOut *dataOut 28 | res string 29 | err string 30 | }{ 31 | { 32 | name: "Nil", 33 | err: "no data", 34 | }, 35 | { 36 | name: "Normal", 37 | dataOut: &dataOut{ 38 | startTime: time.Unix(1606824023, 0), 39 | }, 40 | res: "2020-12-01 12:00:23 +0000 UTC", 41 | }, 42 | { 43 | name: "Verbose", 44 | dataOut: &dataOut{ 45 | startTime: time.Unix(1606824023, 0), 46 | endTime: time.Unix(1606824035, 0), 47 | verbose: true, 48 | }, 49 | res: "2020-12-01 12:00:23 +0000 UTC - 2020-12-01 12:00:35 +0000 UTC", 50 | }, 51 | } 52 | 53 | for _, test := range tests { 54 | t.Run(test.name, func(t *testing.T) { 55 | res, err := output(context.Background(), test.dataOut) 56 | if test.err != "" { 57 | require.EqualError(t, err, test.err) 58 | } else { 59 | require.NoError(t, err) 60 | require.Equal(t, test.res, res) 61 | } 62 | }) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /cmd/slot/time/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package slottime 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/slottime.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | "github.com/spf13/viper" 21 | slottime "github.com/wealdtech/ethdo/cmd/slot/time" 22 | ) 23 | 24 | var slotTimeCmd = &cobra.Command{ 25 | Use: "time", 26 | Short: "Obtain the time for a slot", 27 | Long: `Obtain the time(s) for a slot. For example: 28 | 29 | ethdo slot time --slot=12345 30 | 31 | In quiet mode this will return 0.`, 32 | RunE: func(cmd *cobra.Command, _ []string) error { 33 | res, err := slottime.Run(cmd) 34 | if err != nil { 35 | return err 36 | } 37 | if viper.GetBool("quiet") { 38 | return nil 39 | } 40 | if res != "" { 41 | fmt.Println(res) 42 | } 43 | return nil 44 | }, 45 | } 46 | 47 | func init() { 48 | slotCmd.AddCommand(slotTimeCmd) 49 | slotFlags(slotTimeCmd) 50 | slotTimeCmd.Flags().String("slot", "", "the ID of the slot to fetch") 51 | } 52 | 53 | func slotTimeBindings(cmd *cobra.Command) { 54 | if err := viper.BindPFlag("slot", cmd.Flags().Lookup("slot")); err != nil { 55 | panic(err) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /cmd/synccommittee.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // synccommitteeCmd represents the synccommittee command. 21 | var synccommitteeCmd = &cobra.Command{ 22 | Use: "synccommittee", 23 | Short: "Obtain information about Ethereum 2 sync committees", 24 | Long: "Obtain information about Ethereum 2 sync committees", 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(synccommitteeCmd) 29 | } 30 | 31 | func synccommitteeFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/synccommittee/inclusion/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package inclusion 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/synccommittee/members/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package members 15 | 16 | import ( 17 | "context" 18 | "encoding/json" 19 | "fmt" 20 | "strings" 21 | 22 | "github.com/attestantio/go-eth2-client/spec/phase0" 23 | "github.com/pkg/errors" 24 | ) 25 | 26 | type dataOut struct { 27 | debug bool 28 | quiet bool 29 | verbose bool 30 | json bool 31 | validators []phase0.ValidatorIndex 32 | } 33 | 34 | func output(_ context.Context, data *dataOut) (string, error) { 35 | if data == nil { 36 | return "", errors.New("no data") 37 | } 38 | 39 | if data.quiet { 40 | return "", nil 41 | } 42 | 43 | if data.validators == nil { 44 | return "No sync committee validators found", nil 45 | } 46 | 47 | if data.json { 48 | bytes, err := json.Marshal(data.validators) 49 | if err != nil { 50 | return "", errors.Wrap(err, "failed to marshal JSON") 51 | } 52 | return string(bytes), nil 53 | } 54 | 55 | validators := make([]string, len(data.validators)) 56 | for i := range data.validators { 57 | validators[i] = fmt.Sprintf("%d", data.validators[i]) 58 | } 59 | 60 | return strings.Join(validators, ","), nil 61 | } 62 | -------------------------------------------------------------------------------- /cmd/synccommittee/members/output_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package members 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/attestantio/go-eth2-client/spec/phase0" 21 | "github.com/stretchr/testify/require" 22 | ) 23 | 24 | func TestOutput(t *testing.T) { 25 | tests := []struct { 26 | name string 27 | dataOut *dataOut 28 | res string 29 | err string 30 | }{ 31 | { 32 | name: "Nil", 33 | err: "no data", 34 | }, 35 | { 36 | name: "Empty", 37 | dataOut: &dataOut{}, 38 | res: "No sync committee validators found", 39 | }, 40 | { 41 | name: "Present", 42 | dataOut: &dataOut{ 43 | validators: []phase0.ValidatorIndex{1, 2, 3}, 44 | }, 45 | res: "1,2,3", 46 | }, 47 | { 48 | name: "JSON", 49 | dataOut: &dataOut{ 50 | json: true, 51 | validators: []phase0.ValidatorIndex{1, 2, 3}, 52 | }, 53 | res: `["1","2","3"]`, 54 | }, 55 | } 56 | 57 | for _, test := range tests { 58 | t.Run(test.name, func(t *testing.T) { 59 | res, err := output(context.Background(), test.dataOut) 60 | if test.err != "" { 61 | require.EqualError(t, err, test.err) 62 | } else { 63 | require.NoError(t, err) 64 | require.Equal(t, test.res, res) 65 | } 66 | }) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /cmd/synccommittee/members/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package members 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validator.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // validatorCmd represents the validator command. 21 | var validatorCmd = &cobra.Command{ 22 | Use: "validator", 23 | Short: "Manage Ethereum 2 validators", 24 | Long: `Manage Ethereum 2 validators.`, 25 | } 26 | 27 | func init() { 28 | RootCmd.AddCommand(validatorCmd) 29 | } 30 | 31 | func validatorFlags(_ *cobra.Command) { 32 | } 33 | 34 | func validatorBindings() { 35 | } 36 | -------------------------------------------------------------------------------- /cmd/validator/credentials/get/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorcredentialsget 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validator/credentials/set/command_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorcredentialsset 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestInput(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "TimeoutMissing", 37 | vars: map[string]interface{}{}, 38 | err: "timeout is required", 39 | }, 40 | { 41 | name: "Good", 42 | vars: map[string]interface{}{ 43 | "timeout": "5s", 44 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 45 | "validator": "1", 46 | }, 47 | }, 48 | } 49 | 50 | for _, test := range tests { 51 | t.Run(test.name, func(t *testing.T) { 52 | viper.Reset() 53 | 54 | for k, v := range test.vars { 55 | viper.Set(k, v) 56 | } 57 | _, err := newCommand(context.Background()) 58 | if test.err != "" { 59 | require.EqualError(t, err, test.err) 60 | } else { 61 | require.NoError(t, err) 62 | } 63 | }) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /cmd/validator/credentials/set/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorcredentialsset 15 | 16 | import ( 17 | "context" 18 | "encoding/json" 19 | "fmt" 20 | "os" 21 | 22 | "github.com/pkg/errors" 23 | ) 24 | 25 | //nolint:unparam 26 | func (c *command) output(_ context.Context) (string, error) { 27 | if c.quiet { 28 | return "", nil 29 | } 30 | 31 | if c.prepareOffline { 32 | return fmt.Sprintf("%s generated", offlinePreparationFilename), nil 33 | } 34 | 35 | if c.json || c.offline { 36 | data, err := json.Marshal(c.signedOperations) 37 | if err != nil { 38 | return "", errors.Wrap(err, "failed to marshal signed operations") 39 | } 40 | if c.json { 41 | return string(data), nil 42 | } 43 | if err := os.WriteFile(changeOperationsFilename, data, 0o600); err != nil { 44 | return "", errors.Wrap(err, fmt.Sprintf("failed to write %s", changeOperationsFilename)) 45 | } 46 | return "", nil 47 | } 48 | 49 | return "", nil 50 | } 51 | -------------------------------------------------------------------------------- /cmd/validator/credentials/set/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorcredentialsset 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validator/depositdata/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package depositdata 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the validator deposit data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | dataIn, err := input() 27 | if err != nil { 28 | return "", errors.Join(errors.New("failed to set up command"), err) 29 | } 30 | 31 | // Further errors do not need a usage report. 32 | cmd.SilenceUsage = true 33 | 34 | dataOut, err := process(dataIn) 35 | if err != nil { 36 | switch { 37 | case errors.Is(err, context.DeadlineExceeded): 38 | return "", errors.New("operation timed out; try increasing with --timeout option") 39 | default: 40 | return "", err 41 | } 42 | } 43 | 44 | if viper.GetBool("quiet") { 45 | return "", nil 46 | } 47 | 48 | results, err := output(dataOut) 49 | if err != nil { 50 | return "", errors.Join(errors.New("failed to obtain output"), err) 51 | } 52 | 53 | return results, nil 54 | } 55 | -------------------------------------------------------------------------------- /cmd/validator/duties/process_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorduties 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | "time" 21 | 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestProcess(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | dataIn *dataIn 33 | err string 34 | }{ 35 | { 36 | name: "Nil", 37 | err: "no data", 38 | }, 39 | { 40 | name: "Client", 41 | dataIn: &dataIn{ 42 | timeout: 5 * time.Second, 43 | eth2Client: os.Getenv("ETHDO_TEST_CONNECTION"), 44 | allowInsecure: true, 45 | index: "1", 46 | }, 47 | }, 48 | } 49 | 50 | for _, test := range tests { 51 | t.Run(test.name, func(t *testing.T) { 52 | _, err := process(context.Background(), test.dataIn) 53 | if test.err != "" { 54 | require.EqualError(t, err, test.err) 55 | } else { 56 | require.NoError(t, err) 57 | } 58 | }) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /cmd/validator/duties/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorduties 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validator/exit/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorexit 15 | 16 | import ( 17 | "context" 18 | "encoding/json" 19 | "fmt" 20 | "os" 21 | 22 | "github.com/pkg/errors" 23 | ) 24 | 25 | //nolint:unparam 26 | func (c *command) output(_ context.Context) (string, error) { 27 | if c.quiet { 28 | return "", nil 29 | } 30 | 31 | if c.prepareOffline { 32 | return fmt.Sprintf("%s generated", offlinePreparationFilename), nil 33 | } 34 | 35 | if c.json || c.offline { 36 | var data []byte 37 | var err error 38 | if len(c.signedOperations) == 1 { 39 | data, err = json.Marshal(c.signedOperations[0]) 40 | } else { 41 | data, err = json.Marshal(c.signedOperations) 42 | } 43 | if err != nil { 44 | return "", errors.Wrap(err, "failed to marshal signed operations") 45 | } 46 | if c.json { 47 | return string(data), nil 48 | } 49 | if err := os.WriteFile(exitOperationsFilename, data, 0o600); err != nil { 50 | return "", errors.Wrap(err, fmt.Sprintf("failed to write %s", exitOperationsFilename)) 51 | } 52 | return "", nil 53 | } 54 | 55 | return "", nil 56 | } 57 | -------------------------------------------------------------------------------- /cmd/validator/exit/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorexit 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validator/expectation/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2023 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorexpectation 15 | 16 | import ( 17 | "context" 18 | "encoding/json" 19 | "fmt" 20 | "strings" 21 | 22 | "github.com/hako/durafmt" 23 | ) 24 | 25 | func (c *command) output(ctx context.Context) (string, error) { 26 | if c.quiet { 27 | return "", nil 28 | } 29 | 30 | if c.json { 31 | return c.outputJSON(ctx) 32 | } 33 | return c.outputTxt(ctx) 34 | } 35 | 36 | func (c *command) outputJSON(_ context.Context) (string, error) { 37 | data, err := json.Marshal(c.res) 38 | if err != nil { 39 | return "", err 40 | } 41 | 42 | return fmt.Sprintf("%s\n", string(data)), nil 43 | } 44 | 45 | func (c *command) outputTxt(_ context.Context) (string, error) { 46 | builder := strings.Builder{} 47 | 48 | builder.WriteString("Expected time between block proposals: ") 49 | builder.WriteString(durafmt.Parse(c.res.timeBetweenProposals).LimitFirstN(2).String()) 50 | builder.WriteString("\n") 51 | 52 | builder.WriteString("Expected time between sync committees: ") 53 | builder.WriteString(durafmt.Parse(c.res.timeBetweenSyncCommittees).LimitFirstN(2).String()) 54 | builder.WriteString("\n") 55 | 56 | return builder.String(), nil 57 | } 58 | -------------------------------------------------------------------------------- /cmd/validator/expectation/process_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorexpectation 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestProcess(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "InvalidData", 37 | vars: map[string]interface{}{ 38 | "timeout": "60s", 39 | "validators": "1", 40 | "data": "[[", 41 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 42 | }, 43 | }, 44 | } 45 | 46 | for _, test := range tests { 47 | t.Run(test.name, func(t *testing.T) { 48 | viper.Reset() 49 | 50 | for k, v := range test.vars { 51 | viper.Set(k, v) 52 | } 53 | cmd, err := newCommand(context.Background()) 54 | require.NoError(t, err) 55 | err = cmd.process(context.Background()) 56 | if test.err != "" { 57 | require.EqualError(t, err, test.err) 58 | } else { 59 | require.NoError(t, err) 60 | } 61 | }) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /cmd/validator/expectation/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorexpectation 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validator/keycheck/input.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorkeycheck 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/pkg/errors" 20 | "github.com/spf13/viper" 21 | ) 22 | 23 | type dataIn struct { 24 | // System. 25 | quiet bool 26 | verbose bool 27 | debug bool 28 | // Withdrawal credentials. 29 | withdrawalCredentials string 30 | // Operation. 31 | mnemonic string 32 | privKey string 33 | } 34 | 35 | func input(_ context.Context) (*dataIn, error) { 36 | data := &dataIn{} 37 | 38 | data.quiet = viper.GetBool("quiet") 39 | data.verbose = viper.GetBool("verbose") 40 | data.debug = viper.GetBool("debug") 41 | 42 | // Withdrawal credentials. 43 | data.withdrawalCredentials = viper.GetString("withdrawal-credentials") 44 | if data.withdrawalCredentials == "" { 45 | return nil, errors.New("withdrawal credentials are required") 46 | } 47 | 48 | data.mnemonic = viper.GetString("mnemonic") 49 | data.privKey = viper.GetString("private-key") 50 | if data.mnemonic == "" && data.privKey == "" { 51 | return nil, errors.New("mnemonic or private key is required") 52 | } 53 | 54 | return data, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validator/keycheck/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorkeycheck 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | "os" 20 | 21 | "github.com/pkg/errors" 22 | ) 23 | 24 | type dataOut struct { 25 | debug bool 26 | quiet bool 27 | verbose bool 28 | match bool 29 | path string 30 | } 31 | 32 | func output(_ context.Context, data *dataOut) (string, int, error) { 33 | if data == nil { 34 | return "", 1, errors.New("no data") 35 | } 36 | 37 | if data.quiet { 38 | if !data.match { 39 | os.Exit(1) 40 | } 41 | return "", 1, nil 42 | } 43 | 44 | if data.match { 45 | if data.path == "" { 46 | return "Withdrawal credentials confirmed", 0, nil 47 | } 48 | return fmt.Sprintf("Withdrawal credentials confirmed at path %s", data.path), 0, nil 49 | } 50 | 51 | return "Could not confirm withdrawal credentials with given information", 1, nil 52 | } 53 | -------------------------------------------------------------------------------- /cmd/validator/keycheck/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorkeycheck 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | "fmt" 20 | "os" 21 | 22 | "github.com/spf13/cobra" 23 | ) 24 | 25 | // Run runs the wallet create data command. 26 | func Run(cmd *cobra.Command) (string, error) { 27 | ctx := context.Background() 28 | dataIn, err := input(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | dataOut, err := process(ctx, dataIn) 37 | if err != nil { 38 | switch { 39 | case errors.Is(err, context.DeadlineExceeded): 40 | return "", errors.New("operation timed out; try increasing with --timeout option") 41 | default: 42 | return "", errors.Join(errors.New("failed to process"), err) 43 | } 44 | } 45 | 46 | results, exitCode, err := output(ctx, dataOut) 47 | if err != nil { 48 | return "", errors.Join(errors.New("failed to obtain output"), err) 49 | } 50 | if exitCode != 0 { 51 | fmt.Println(results) 52 | os.Exit(exitCode) 53 | } 54 | 55 | return results, nil 56 | } 57 | -------------------------------------------------------------------------------- /cmd/validator/summary/command_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorsummary 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestInput(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "TimeoutMissing", 37 | vars: map[string]interface{}{}, 38 | err: "timeout is required", 39 | }, 40 | { 41 | name: "Good", 42 | vars: map[string]interface{}{ 43 | "timeout": "5s", 44 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 45 | }, 46 | }, 47 | } 48 | 49 | for _, test := range tests { 50 | t.Run(test.name, func(t *testing.T) { 51 | viper.Reset() 52 | 53 | for k, v := range test.vars { 54 | viper.Set(k, v) 55 | } 56 | _, err := newCommand(context.Background()) 57 | if test.err != "" { 58 | require.EqualError(t, err, test.err) 59 | } else { 60 | require.NoError(t, err) 61 | } 62 | }) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /cmd/validator/summary/process_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorsummary 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestProcess(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "InvalidData", 37 | vars: map[string]interface{}{ 38 | "timeout": "60s", 39 | "data": "[[", 40 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 41 | }, 42 | }, 43 | } 44 | 45 | for _, test := range tests { 46 | t.Run(test.name, func(t *testing.T) { 47 | viper.Reset() 48 | 49 | for k, v := range test.vars { 50 | viper.Set(k, v) 51 | } 52 | cmd, err := newCommand(context.Background()) 53 | require.NoError(t, err) 54 | err = cmd.process(context.Background()) 55 | if test.err != "" { 56 | require.EqualError(t, err, test.err) 57 | } else { 58 | require.NoError(t, err) 59 | } 60 | }) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /cmd/validator/summary/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorsummary 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validator/withdrawal/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorwithdrawl 15 | 16 | import ( 17 | "context" 18 | "encoding/json" 19 | "fmt" 20 | 21 | "github.com/pkg/errors" 22 | ) 23 | 24 | //nolint:unparam 25 | func (c *command) output(_ context.Context) (string, error) { 26 | if c.quiet { 27 | return "", nil 28 | } 29 | 30 | if c.json { 31 | data, err := json.Marshal(c.res) 32 | if err != nil { 33 | return "", errors.Wrap(err, "failed to marshal results") 34 | } 35 | return string(data), nil 36 | } 37 | 38 | return fmt.Sprintf("Withdrawal expected at %s in block %d", c.res.Expected.Format("2006-01-02T15:04:05"), c.res.Block), nil 39 | } 40 | -------------------------------------------------------------------------------- /cmd/validator/withdrawal/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatorwithdrawl 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validator/yield/command_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatoryield 15 | 16 | import ( 17 | "context" 18 | "os" 19 | "testing" 20 | 21 | "github.com/spf13/viper" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestInput(t *testing.T) { 26 | if os.Getenv("ETHDO_TEST_CONNECTION") == "" { 27 | t.Skip("ETHDO_TEST_CONNECTION not configured; cannot run tests") 28 | } 29 | 30 | tests := []struct { 31 | name string 32 | vars map[string]interface{} 33 | err string 34 | }{ 35 | { 36 | name: "TimeoutMissing", 37 | vars: map[string]interface{}{}, 38 | err: "timeout is required", 39 | }, 40 | { 41 | name: "Good", 42 | vars: map[string]interface{}{ 43 | "validators": "1", 44 | "timeout": "5s", 45 | "connection": os.Getenv("ETHDO_TEST_CONNECTION"), 46 | }, 47 | }, 48 | } 49 | 50 | for _, test := range tests { 51 | t.Run(test.name, func(t *testing.T) { 52 | viper.Reset() 53 | 54 | for k, v := range test.vars { 55 | viper.Set(k, v) 56 | } 57 | _, err := newCommand(context.Background()) 58 | if test.err != "" { 59 | require.EqualError(t, err, test.err) 60 | } else { 61 | require.NoError(t, err) 62 | } 63 | }) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /cmd/validator/yield/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package validatoryield 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validatorcredentials.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | ) 19 | 20 | // validatorCredentialsCmd represents the validator credentials command. 21 | var validatorCredentialsCmd = &cobra.Command{ 22 | Use: "credentials", 23 | Short: "Manage Ethereum consensus validator credentials", 24 | Long: `Manage Ethereum consensus validator credentials.`, 25 | } 26 | 27 | func init() { 28 | validatorCmd.AddCommand(validatorCredentialsCmd) 29 | } 30 | 31 | func validatorCredentialsFlags(_ *cobra.Command) { 32 | } 33 | -------------------------------------------------------------------------------- /cmd/validatorexpectation.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | "strings" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | validatorexpectation "github.com/wealdtech/ethdo/cmd/validator/expectation" 23 | ) 24 | 25 | var validatorExpectationCmd = &cobra.Command{ 26 | Use: "expectation", 27 | Short: "Calculate expectation for individual validators", 28 | Long: `Calculate expectation for individual validators. For example: 29 | 30 | ethdo validator expectation`, 31 | RunE: func(cmd *cobra.Command, _ []string) error { 32 | res, err := validatorexpectation.Run(cmd) 33 | if err != nil { 34 | return err 35 | } 36 | if viper.GetBool("quiet") { 37 | return nil 38 | } 39 | res = strings.TrimRight(res, "\n") 40 | fmt.Println(res) 41 | return nil 42 | }, 43 | } 44 | 45 | func init() { 46 | validatorCmd.AddCommand(validatorExpectationCmd) 47 | validatorFlags(validatorExpectationCmd) 48 | validatorExpectationCmd.Flags().Int64("validators", 1, "Number of validators") 49 | } 50 | 51 | func validatorExpectationBindings(cmd *cobra.Command) { 52 | if err := viper.BindPFlag("validators", cmd.Flags().Lookup("validators")); err != nil { 53 | panic(err) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /cmd/validatorwithdrawal.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | "github.com/spf13/viper" 21 | validatorwithdrawal "github.com/wealdtech/ethdo/cmd/validator/withdrawal" 22 | ) 23 | 24 | var validatorWithdrawalCmd = &cobra.Command{ 25 | Use: "withdrawal", 26 | Short: "Obtain next withdrawal for a validator", 27 | Long: `Obtain next withdrawal for a validator. For example: 28 | 29 | ethdo validator withdrawal --validator=primary/validator 30 | 31 | In quiet mode this will return 0 if the validator exists, otherwise 1.`, 32 | RunE: func(cmd *cobra.Command, _ []string) error { 33 | res, err := validatorwithdrawal.Run(cmd) 34 | if err != nil { 35 | return err 36 | } 37 | if viper.GetBool("quiet") { 38 | return nil 39 | } 40 | if res != "" { 41 | fmt.Println(res) 42 | } 43 | return nil 44 | }, 45 | } 46 | 47 | func init() { 48 | validatorCmd.AddCommand(validatorWithdrawalCmd) 49 | validatorFlags(validatorWithdrawalCmd) 50 | validatorWithdrawalCmd.Flags().String("validator", "", "Validator for which to get withdrawal") 51 | } 52 | 53 | func validatorWithdrawalBindings(cmd *cobra.Command) { 54 | if err := viper.BindPFlag("validator", cmd.Flags().Lookup("validator")); err != nil { 55 | panic(err) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /cmd/wallet.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "github.com/spf13/cobra" 18 | "github.com/spf13/pflag" 19 | "github.com/spf13/viper" 20 | ) 21 | 22 | // walletCmd represents the wallet command. 23 | var walletCmd = &cobra.Command{ 24 | Use: "wallet", 25 | Short: "Manage wallets", 26 | Long: `Create and manage wallets.`, 27 | } 28 | 29 | func init() { 30 | RootCmd.AddCommand(walletCmd) 31 | } 32 | 33 | var walletFlag *pflag.Flag 34 | 35 | func walletFlags(cmd *cobra.Command) { 36 | if walletFlag == nil { 37 | cmd.Flags().String("wallet", "", "Name of the wallet") 38 | walletFlag = cmd.Flags().Lookup("wallet") 39 | if err := viper.BindPFlag("wallet", walletFlag); err != nil { 40 | panic(err) 41 | } 42 | } else { 43 | cmd.Flags().AddFlag(walletFlag) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /cmd/wallet/batch/command.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletbatch 15 | 16 | import ( 17 | "context" 18 | "time" 19 | 20 | "github.com/pkg/errors" 21 | "github.com/spf13/viper" 22 | "github.com/wealdtech/ethdo/util" 23 | ) 24 | 25 | type command struct { 26 | quiet bool 27 | verbose bool 28 | debug bool 29 | 30 | timeout time.Duration 31 | 32 | // Operation. 33 | walletName string 34 | passphrases []string 35 | batchPassphrase string 36 | } 37 | 38 | func newCommand(_ context.Context) (*command, error) { 39 | c := &command{ 40 | quiet: viper.GetBool("quiet"), 41 | verbose: viper.GetBool("verbose"), 42 | debug: viper.GetBool("debug"), 43 | timeout: viper.GetDuration("timeout"), 44 | walletName: viper.GetString("wallet"), 45 | passphrases: util.GetPassphrases(), 46 | batchPassphrase: viper.GetString("batch-passphrase"), 47 | } 48 | 49 | if c.timeout == 0 { 50 | return nil, errors.New("timeout is required") 51 | } 52 | 53 | if c.walletName == "" { 54 | return nil, errors.New("wallet is required") 55 | } 56 | 57 | if c.batchPassphrase == "" { 58 | return nil, errors.New("batch passphrase is required") 59 | } 60 | 61 | return c, nil 62 | } 63 | -------------------------------------------------------------------------------- /cmd/wallet/batch/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletbatch 15 | 16 | import ( 17 | "context" 18 | ) 19 | 20 | func (c *command) output(_ context.Context) (string, error) { 21 | return "", nil 22 | } 23 | -------------------------------------------------------------------------------- /cmd/wallet/batch/process.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletbatch 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/pkg/errors" 20 | "github.com/wealdtech/ethdo/util" 21 | e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2" 22 | ) 23 | 24 | func (c *command) process(ctx context.Context) error { 25 | // Obtain the wallet. 26 | opCtx, cancel := context.WithTimeout(ctx, c.timeout) 27 | wallet, err := util.WalletFromInput(opCtx) 28 | cancel() 29 | if err != nil { 30 | return errors.Wrap(err, "failed to obtain wallet") 31 | } 32 | batchCreator, isBatchCreator := wallet.(e2wtypes.WalletBatchCreator) 33 | if !isBatchCreator { 34 | return errors.New("wallet does not support batching") 35 | } 36 | 37 | // Create the batch. 38 | if err := batchCreator.BatchWallet(ctx, util.GetPassphrases(), c.batchPassphrase); err != nil { 39 | return errors.Wrap(err, "failed to batch wallet") 40 | } 41 | 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /cmd/wallet/batch/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletbatch 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | 28 | c, err := newCommand(ctx) 29 | if err != nil { 30 | return "", errors.Join(errors.New("failed to set up command"), err) 31 | } 32 | 33 | // Further errors do not need a usage report. 34 | cmd.SilenceUsage = true 35 | 36 | if err := c.process(ctx); err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := c.output(ctx) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/wallet/create/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletcreate 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | 20 | "github.com/pkg/errors" 21 | ) 22 | 23 | type dataOut struct { 24 | mnemonic string 25 | } 26 | 27 | func output(_ context.Context, data *dataOut) (string, error) { 28 | if data == nil { 29 | return "", errors.New("no data") 30 | } 31 | if data.mnemonic != "" { 32 | return fmt.Sprintf(`The following phrase is your mnemonic for this wallet: 33 | 34 | %s 35 | 36 | Anyone with access to this mnemonic can recreate the accounts in this wallet, so please store this mnemonic safely. More information about mnemonics can be found at https://support.mycrypto.com/general-knowledge/cryptography/how-do-mnemonic-phrases-work 37 | 38 | Please note this mnemonic is not stored within the wallet, so cannot be retrieved or displayed again. As such, this mnemonic should be stored securely, ideally offline, before proceeding. 39 | `, data.mnemonic), nil 40 | } 41 | 42 | return "", nil 43 | } 44 | -------------------------------------------------------------------------------- /cmd/wallet/create/output_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletcreate 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/require" 21 | ) 22 | 23 | func TestOutput(t *testing.T) { 24 | tests := []struct { 25 | name string 26 | dataOut *dataOut 27 | res bool 28 | err string 29 | }{ 30 | { 31 | name: "Nil", 32 | err: "no data", 33 | }, 34 | { 35 | name: "Good", 36 | dataOut: &dataOut{}, 37 | }, 38 | { 39 | name: "GoodMnemonic", 40 | dataOut: &dataOut{ 41 | mnemonic: "test mnemonic", 42 | }, 43 | res: true, 44 | }, 45 | } 46 | 47 | for _, test := range tests { 48 | t.Run(test.name, func(t *testing.T) { 49 | res, err := output(context.Background(), test.dataOut) 50 | if test.err != "" { 51 | require.EqualError(t, err, test.err) 52 | } else { 53 | require.NoError(t, err) 54 | if test.res { 55 | require.NotEqual(t, "", res) 56 | } else { 57 | require.Equal(t, "", res) 58 | } 59 | } 60 | }) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /cmd/wallet/create/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletcreate 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/wallet/delete/input.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletdelete 15 | 16 | import ( 17 | "context" 18 | "time" 19 | 20 | "github.com/pkg/errors" 21 | "github.com/spf13/viper" 22 | "github.com/wealdtech/ethdo/util" 23 | e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2" 24 | ) 25 | 26 | type dataIn struct { 27 | // System. 28 | timeout time.Duration 29 | quiet bool 30 | verbose bool 31 | debug bool 32 | wallet e2wtypes.Wallet 33 | } 34 | 35 | func input(ctx context.Context) (*dataIn, error) { 36 | var err error 37 | data := &dataIn{} 38 | 39 | if viper.GetString("remote") != "" { 40 | return nil, errors.New("wallet delete not available for remote wallets") 41 | } 42 | 43 | if viper.GetDuration("timeout") == 0 { 44 | return nil, errors.New("timeout is required") 45 | } 46 | data.timeout = viper.GetDuration("timeout") 47 | data.quiet = viper.GetBool("quiet") 48 | data.verbose = viper.GetBool("verbose") 49 | data.debug = viper.GetBool("debug") 50 | 51 | // Wallet. 52 | wallet, err := util.WalletFromInput(ctx) 53 | if err != nil { 54 | return nil, errors.Wrap(err, "failed to access wallet") 55 | } 56 | data.wallet = wallet 57 | 58 | return data, nil 59 | } 60 | -------------------------------------------------------------------------------- /cmd/wallet/delete/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletdelete 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/pkg/errors" 20 | ) 21 | 22 | type dataOut struct{} 23 | 24 | func output(_ context.Context, data *dataOut) (string, error) { 25 | if data == nil { 26 | return "", errors.New("no data") 27 | } 28 | return "", nil 29 | } 30 | -------------------------------------------------------------------------------- /cmd/wallet/delete/output_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletdelete 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/require" 21 | ) 22 | 23 | func TestOutput(t *testing.T) { 24 | tests := []struct { 25 | name string 26 | dataOut *dataOut 27 | err string 28 | }{ 29 | { 30 | name: "Nil", 31 | err: "no data", 32 | }, 33 | { 34 | name: "Good", 35 | dataOut: &dataOut{}, 36 | }, 37 | } 38 | 39 | for _, test := range tests { 40 | t.Run(test.name, func(t *testing.T) { 41 | res, err := output(context.Background(), test.dataOut) 42 | if test.err != "" { 43 | require.EqualError(t, err, test.err) 44 | } else { 45 | require.NoError(t, err) 46 | require.Equal(t, "", res) 47 | } 48 | }) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /cmd/wallet/delete/process.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletdelete 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | "os" 20 | "path/filepath" 21 | 22 | "github.com/pkg/errors" 23 | e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2" 24 | ) 25 | 26 | func process(_ context.Context, data *dataIn) (*dataOut, error) { 27 | if data == nil { 28 | return nil, errors.New("no data") 29 | } 30 | if data.wallet == nil { 31 | return nil, errors.New("wallet is required") 32 | } 33 | 34 | storeProvider, isProvider := data.wallet.(e2wtypes.StoreProvider) 35 | if !isProvider { 36 | return nil, errors.New("cannot obtain store for the wallet") 37 | } 38 | store := storeProvider.Store() 39 | 40 | if store.Name() != "filesystem" { 41 | return nil, fmt.Errorf("cannot delete %s wallet automatically, please remove manually", store.Name()) 42 | } 43 | storeLocationProvider, isProvider := store.(e2wtypes.StoreLocationProvider) 44 | if !isProvider { 45 | return nil, errors.New("cannot obtain store location for the wallet") 46 | } 47 | walletLocation := filepath.Join(storeLocationProvider.Location(), data.wallet.ID().String()) 48 | if err := os.RemoveAll(walletLocation); err != nil { 49 | return nil, errors.Wrap(err, "failed to delete wallet") 50 | } 51 | 52 | return &dataOut{}, nil 53 | } 54 | -------------------------------------------------------------------------------- /cmd/wallet/delete/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletdelete 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if !viper.GetBool("verbose") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/wallet/export/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletexport 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | 20 | "github.com/pkg/errors" 21 | ) 22 | 23 | type dataOut struct { 24 | export []byte 25 | } 26 | 27 | func output(_ context.Context, data *dataOut) (string, error) { 28 | if data == nil { 29 | return "", errors.New("no data") 30 | } 31 | 32 | return fmt.Sprintf("%#x", data.export), nil 33 | } 34 | -------------------------------------------------------------------------------- /cmd/wallet/export/output_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletexport 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/require" 21 | ) 22 | 23 | func TestOutput(t *testing.T) { 24 | tests := []struct { 25 | name string 26 | dataOut *dataOut 27 | err string 28 | }{ 29 | { 30 | name: "Nil", 31 | err: "no data", 32 | }, 33 | { 34 | name: "Good", 35 | dataOut: &dataOut{}, 36 | }, 37 | } 38 | 39 | for _, test := range tests { 40 | t.Run(test.name, func(t *testing.T) { 41 | res, err := output(context.Background(), test.dataOut) 42 | if test.err != "" { 43 | require.EqualError(t, err, test.err) 44 | } else { 45 | require.NoError(t, err) 46 | require.Equal(t, "", res) 47 | } 48 | }) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /cmd/wallet/export/process.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletexport 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/pkg/errors" 20 | "github.com/wealdtech/ethdo/util" 21 | e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2" 22 | ) 23 | 24 | func process(ctx context.Context, data *dataIn) (*dataOut, error) { 25 | if data == nil { 26 | return nil, errors.New("no data") 27 | } 28 | if data.wallet == nil { 29 | return nil, errors.New("wallet is required") 30 | } 31 | if !util.AcceptablePassphrase(data.passphrase) { 32 | return nil, errors.New("supplied passphrase is weak; use a stronger one or run with the --allow-weak-passphrases flag") 33 | } 34 | 35 | exporter, isExporter := data.wallet.(e2wtypes.WalletExporter) 36 | if !isExporter { 37 | return nil, errors.New("wallet does not provide export") 38 | } 39 | 40 | export, err := exporter.Export(ctx, []byte(data.passphrase)) 41 | if err != nil { 42 | return nil, errors.Wrap(err, "failed to export wallet") 43 | } 44 | 45 | results := &dataOut{ 46 | export: export, 47 | } 48 | 49 | return results, nil 50 | } 51 | -------------------------------------------------------------------------------- /cmd/wallet/export/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletexport 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/wallet/import/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletimport 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | 20 | "github.com/gofrs/uuid" 21 | "github.com/pkg/errors" 22 | ) 23 | 24 | type dataOut struct { 25 | verify bool 26 | quiet bool 27 | verbose bool 28 | export *export 29 | } 30 | 31 | type accountInfo struct { 32 | Name string `json:"name"` 33 | } 34 | type walletInfo struct { 35 | ID uuid.UUID `json:"uuid"` 36 | Name string `json:"name"` 37 | Type string `json:"type"` 38 | } 39 | type export struct { 40 | Wallet *walletInfo `json:"wallet"` 41 | Accounts []*accountInfo `json:"accounts"` 42 | } 43 | 44 | func output(_ context.Context, data *dataOut) (string, error) { 45 | if data == nil { 46 | return "", errors.New("no data") 47 | } 48 | 49 | res := "" 50 | if data.verify { 51 | if !data.quiet { 52 | res = fmt.Sprintf("Wallet name: %s\nWallet type: %s\nWallet UUID: %s\nWallet accounts: %d", data.export.Wallet.Name, data.export.Wallet.Type, data.export.Wallet.ID, len(data.export.Accounts)) 53 | if data.verbose { 54 | for _, account := range data.export.Accounts { 55 | res = fmt.Sprintf("%s\n %s", res, account.Name) 56 | } 57 | } 58 | } 59 | } 60 | 61 | return res, nil 62 | } 63 | -------------------------------------------------------------------------------- /cmd/wallet/import/process.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletimport 15 | 16 | import ( 17 | "context" 18 | "encoding/json" 19 | 20 | "github.com/pkg/errors" 21 | "github.com/wealdtech/go-ecodec" 22 | e2wallet "github.com/wealdtech/go-eth2-wallet" 23 | ) 24 | 25 | func process(_ context.Context, data *dataIn) (*dataOut, error) { 26 | if data == nil { 27 | return nil, errors.New("no data") 28 | } 29 | if data.data == nil { 30 | return nil, errors.New("import data is required") 31 | } 32 | 33 | ext := &export{} 34 | if data.verify { 35 | data, err := ecodec.Decrypt(data.data, []byte(data.passphrase)) 36 | if err != nil { 37 | return nil, errors.Wrap(err, "failed to decrypt export") 38 | } 39 | if err := json.Unmarshal(data, ext); err != nil { 40 | return nil, errors.Wrap(err, "failed to read export") 41 | } 42 | } else if _, err := e2wallet.ImportWallet(data.data, []byte(data.passphrase)); err != nil { 43 | return nil, errors.Wrap(err, "failed to import wallet") 44 | } 45 | 46 | results := &dataOut{ 47 | verify: data.verify, 48 | export: ext, 49 | } 50 | 51 | return results, nil 52 | } 53 | -------------------------------------------------------------------------------- /cmd/wallet/import/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 - 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletimport 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the wallet create data command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/wallet/sharedexport/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletsharedexport 15 | 16 | import ( 17 | "context" 18 | "encoding/hex" 19 | "strings" 20 | 21 | "github.com/pkg/errors" 22 | ) 23 | 24 | type dataOut struct { 25 | shares [][]byte 26 | } 27 | 28 | func output(_ context.Context, data *dataOut) (string, error) { 29 | if data == nil { 30 | return "", errors.New("no data") 31 | } 32 | 33 | builder := strings.Builder{} 34 | for i := range data.shares { 35 | builder.WriteString(hex.EncodeToString(data.shares[i])) 36 | if i != len(data.shares)-1 { 37 | builder.WriteString("\n") 38 | } 39 | } 40 | 41 | return builder.String(), nil 42 | } 43 | -------------------------------------------------------------------------------- /cmd/wallet/sharedexport/output_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletsharedexport 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/require" 21 | ) 22 | 23 | func TestOutput(t *testing.T) { 24 | tests := []struct { 25 | name string 26 | dataOut *dataOut 27 | expected string 28 | err string 29 | }{ 30 | { 31 | name: "Nil", 32 | err: "no data", 33 | }, 34 | { 35 | name: "Good", 36 | dataOut: &dataOut{ 37 | shares: [][]byte{ 38 | {0x01, 0x02}, 39 | {0x02, 0x03}, 40 | {0x03, 0x04}, 41 | }, 42 | }, 43 | expected: "0102\n0203\n0304", 44 | }, 45 | } 46 | 47 | for _, test := range tests { 48 | t.Run(test.name, func(t *testing.T) { 49 | res, err := output(context.Background(), test.dataOut) 50 | if test.err != "" { 51 | require.EqualError(t, err, test.err) 52 | } else { 53 | require.NoError(t, err) 54 | require.Equal(t, test.expected, res) 55 | } 56 | }) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /cmd/wallet/sharedexport/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletsharedexport 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/wallet/sharedimport/output.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletsharedimport 15 | 16 | import ( 17 | "context" 18 | ) 19 | 20 | type dataOut struct{} 21 | 22 | func output(_ context.Context, _ *dataOut) (string, error) { 23 | return "Wallet imported", nil 24 | } 25 | -------------------------------------------------------------------------------- /cmd/wallet/sharedimport/output_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletsharedimport 15 | 16 | import ( 17 | "context" 18 | "testing" 19 | 20 | "github.com/stretchr/testify/require" 21 | ) 22 | 23 | func TestOutput(t *testing.T) { 24 | tests := []struct { 25 | name string 26 | dataOut *dataOut 27 | res string 28 | err string 29 | }{ 30 | { 31 | name: "Good", 32 | res: "Wallet imported", 33 | }, 34 | } 35 | 36 | for _, test := range tests { 37 | t.Run(test.name, func(t *testing.T) { 38 | res, err := output(context.Background(), test.dataOut) 39 | if test.err != "" { 40 | require.EqualError(t, err, test.err) 41 | } else { 42 | require.NoError(t, err) 43 | require.Equal(t, test.res, res) 44 | } 45 | }) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /cmd/wallet/sharedimport/run.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021, 2024 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package walletsharedimport 15 | 16 | import ( 17 | "context" 18 | "errors" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | // Run runs the command. 25 | func Run(cmd *cobra.Command) (string, error) { 26 | ctx := context.Background() 27 | dataIn, err := input(ctx) 28 | if err != nil { 29 | return "", errors.Join(errors.New("failed to set up command"), err) 30 | } 31 | 32 | // Further errors do not need a usage report. 33 | cmd.SilenceUsage = true 34 | 35 | dataOut, err := process(ctx, dataIn) 36 | if err != nil { 37 | switch { 38 | case errors.Is(err, context.DeadlineExceeded): 39 | return "", errors.New("operation timed out; try increasing with --timeout option") 40 | default: 41 | return "", errors.Join(errors.New("failed to process"), err) 42 | } 43 | } 44 | 45 | if viper.GetBool("quiet") { 46 | return "", nil 47 | } 48 | 49 | results, err := output(ctx, dataOut) 50 | if err != nil { 51 | return "", errors.Join(errors.New("failed to obtain output"), err) 52 | } 53 | 54 | return results, nil 55 | } 56 | -------------------------------------------------------------------------------- /cmd/walletbatch.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 Weald Technology Trading. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | "github.com/spf13/viper" 21 | walletbatch "github.com/wealdtech/ethdo/cmd/wallet/batch" 22 | ) 23 | 24 | var walletBatchCmd = &cobra.Command{ 25 | Use: "batch", 26 | Short: "Batch a wallet", 27 | Long: `Batch a wallet. For example: 28 | 29 | ethdo wallet batch --wallet="Primary wallet" --passphrase=accounts-secret --batch-passphrase=batch-secret 30 | 31 | In quiet mode this will return 0 if the wallet is batched successfully, otherwise 1.`, 32 | RunE: func(cmd *cobra.Command, _ []string) error { 33 | res, err := walletbatch.Run(cmd) 34 | if err != nil { 35 | return err 36 | } 37 | if res != "" { 38 | fmt.Println(res) 39 | } 40 | return nil 41 | }, 42 | } 43 | 44 | func init() { 45 | walletCmd.AddCommand(walletBatchCmd) 46 | walletFlags(walletBatchCmd) 47 | walletBatchCmd.Flags().String("batch-passphrase", "", "The passphrase to use for the batch") 48 | } 49 | 50 | func walletBatchBindings(cmd *cobra.Command) { 51 | if err := viper.BindPFlag("batch-passphrase", cmd.Flags().Lookup("batch-passphrase")); err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /cmd/walletcreate.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | "github.com/spf13/viper" 21 | walletcreate "github.com/wealdtech/ethdo/cmd/wallet/create" 22 | ) 23 | 24 | var walletCreateCmd = &cobra.Command{ 25 | Use: "create", 26 | Short: "Create a wallet", 27 | Long: `Create a wallet. For example: 28 | 29 | ethdo wallet create --wallet="Primary wallet" --type=non-deterministic 30 | 31 | In quiet mode this will return 0 if the wallet is created successfully, otherwise 1.`, 32 | RunE: func(cmd *cobra.Command, _ []string) error { 33 | res, err := walletcreate.Run(cmd) 34 | if err != nil { 35 | return err 36 | } 37 | if res != "" { 38 | fmt.Println(res) 39 | } 40 | return nil 41 | }, 42 | } 43 | 44 | func init() { 45 | walletCmd.AddCommand(walletCreateCmd) 46 | walletFlags(walletCreateCmd) 47 | walletCreateCmd.Flags().String("type", "non-deterministic", "Type of wallet to create (non-deterministic or hierarchical deterministic)") 48 | } 49 | 50 | func walletCreateBindings(cmd *cobra.Command) { 51 | if err := viper.BindPFlag("type", cmd.Flags().Lookup("type")); err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /cmd/walletdelete.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | walletdelete "github.com/wealdtech/ethdo/cmd/wallet/delete" 21 | ) 22 | 23 | var walletDeleteCmd = &cobra.Command{ 24 | Use: "delete", 25 | Short: "Delete a wallet", 26 | Long: `Delete a wallet. For example: 27 | 28 | ethdo wallet delete --wallet=primary 29 | 30 | In quiet mode this will return 0 if the wallet has been deleted, otherwise 1.`, 31 | RunE: func(cmd *cobra.Command, _ []string) error { 32 | res, err := walletdelete.Run(cmd) 33 | if err != nil { 34 | return err 35 | } 36 | if res != "" { 37 | fmt.Println(res) 38 | } 39 | return nil 40 | }, 41 | } 42 | 43 | func init() { 44 | walletCmd.AddCommand(walletDeleteCmd) 45 | walletFlags(walletDeleteCmd) 46 | } 47 | -------------------------------------------------------------------------------- /cmd/walletexport.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/spf13/cobra" 20 | walletexport "github.com/wealdtech/ethdo/cmd/wallet/export" 21 | ) 22 | 23 | var walletExportCmd = &cobra.Command{ 24 | Use: "export", 25 | Short: "Export a wallet", 26 | Long: `Export a wallet for backup of transfer. For example: 27 | 28 | ethdo wallet export --wallet=primary --passphrase="my export secret" 29 | 30 | In quiet mode this will return 0 if the wallet is able to be exported, otherwise 1.`, 31 | RunE: func(cmd *cobra.Command, _ []string) error { 32 | res, err := walletexport.Run(cmd) 33 | if err != nil { 34 | return err 35 | } 36 | if res != "" { 37 | fmt.Println(res) 38 | } 39 | return nil 40 | }, 41 | } 42 | 43 | func init() { 44 | walletCmd.AddCommand(walletExportCmd) 45 | walletFlags(walletExportCmd) 46 | } 47 | -------------------------------------------------------------------------------- /cmd/walletlist.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package cmd 15 | 16 | import ( 17 | "fmt" 18 | "os" 19 | 20 | "github.com/spf13/cobra" 21 | "github.com/spf13/viper" 22 | e2wallet "github.com/wealdtech/go-eth2-wallet" 23 | ) 24 | 25 | var walletListCmd = &cobra.Command{ 26 | Use: "list", 27 | Short: "List known wallets", 28 | Long: `Provide information about local wallets. For example: 29 | 30 | ethdo wallet list 31 | 32 | In quiet mode this will return 0 if any wallets are found, otherwise 1.`, 33 | Run: func(_ *cobra.Command, _ []string) { 34 | assert(viper.GetString("remote") == "", "wallet list not available with remote wallets") 35 | assert(viper.GetString("wallet") == "", "wallet list does not take a --wallet parameter") 36 | 37 | walletsFound := false 38 | for w := range e2wallet.Wallets() { 39 | walletsFound = true 40 | outputIf(!viper.GetBool("quiet") && !viper.GetBool("verbose"), w.Name()) 41 | outputIf(viper.GetBool("verbose"), fmt.Sprintf("%s\n UUID: %s", w.Name(), w.ID().String())) 42 | } 43 | 44 | if !walletsFound { 45 | os.Exit(_exitFailure) 46 | } 47 | os.Exit(_exitSuccess) 48 | }, 49 | } 50 | 51 | func init() { 52 | walletCmd.AddCommand(walletListCmd) 53 | walletFlags(walletListCmd) 54 | } 55 | -------------------------------------------------------------------------------- /docs/images/credentials-change-offline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wealdtech/ethdo/903ecc8581846355c7fb38c5b349b62d9123c3c9/docs/images/credentials-change-offline.png -------------------------------------------------------------------------------- /docs/images/credentials-change-online.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wealdtech/ethdo/903ecc8581846355c7fb38c5b349b62d9123c3c9/docs/images/credentials-change-online.png -------------------------------------------------------------------------------- /docs/images/exit-offline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wealdtech/ethdo/903ecc8581846355c7fb38c5b349b62d9123c3c9/docs/images/exit-offline.png -------------------------------------------------------------------------------- /docs/images/exit-online.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wealdtech/ethdo/903ecc8581846355c7fb38c5b349b62d9123c3c9/docs/images/exit-online.png -------------------------------------------------------------------------------- /docs/troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting 2 | 3 | ## Compilation problems on Linux 4 | 5 | ### gcc not found 6 | ### cannot find -lstdc++ 7 | 8 | If you receive errors of this type your computer is missing some files to allow `ethdo` to build. To resolve this, run the following command: 9 | 10 | ```sh 11 | sudo apt install build-essential libstdc++6 12 | ``` 13 | 14 | and then try to install `ethdo` again. 15 | 16 | ## Compilation problems on Windows 17 | 18 | ### gcc not found 19 | 20 | If you receive errors of this type your computer is missing some files to allow `ethdo` to build. To resolve this install gcc by following the instructions at http://mingw-w64.org/doku.php 21 | 22 | ## ethdo not found after installing 23 | 24 | This is usually due to an incorrectly set path. Go installs its binaries (such as `ethdo`) in a particular location. The defaults are: 25 | 26 | - Linux, Mac: `$HOME/go/bin` 27 | - Windows: `%USERPROFILE%\go\bin` 28 | 29 | You must add these paths to be able to access `ethdo`. To add the path on linux or OSX type: 30 | 31 | ```sh 32 | export PATH=$PATH:$(go env GOPATH)/bin 33 | ``` 34 | 35 | and on Windows type: 36 | 37 | ```sh 38 | setx /M path "%PATH%;%USERPROFILE%\go\bin" 39 | ``` 40 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package main 15 | 16 | import "github.com/wealdtech/ethdo/cmd" 17 | 18 | func main() { 19 | cmd.Execute() 20 | } 21 | -------------------------------------------------------------------------------- /shamir/tables_test.go: -------------------------------------------------------------------------------- 1 | package shamir 2 | 3 | import "testing" 4 | 5 | func TestTables(t *testing.T) { 6 | for i := 1; i < 256; i++ { 7 | logV := logTable[i] 8 | expV := expTable[logV] 9 | if expV != uint8(i) { 10 | t.Fatalf("bad: %d log: %d exp: %d", i, logV, expV) 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /signing/container.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package signing 15 | 16 | // Container contains a root and domain to sign. 17 | type Container struct { 18 | Root []byte `ssz-size:"32"` 19 | Domain []byte `ssz-size:"32"` 20 | } 21 | -------------------------------------------------------------------------------- /signing/generate.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019, 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package signing 15 | 16 | //go:generate sszgen --path . --objs Container 17 | -------------------------------------------------------------------------------- /util/basedir.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util 15 | 16 | import ( 17 | "github.com/spf13/viper" 18 | ) 19 | 20 | // GetBaseDir fetches the base directory for wallets. 21 | func GetBaseDir() string { 22 | baseDir := viper.GetString("base-dir") 23 | if baseDir == "" { 24 | // Try deprecated name. 25 | baseDir = viper.GetString("basedir") 26 | } 27 | return baseDir 28 | } 29 | -------------------------------------------------------------------------------- /util/basedir_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/spf13/viper" 20 | "github.com/stretchr/testify/require" 21 | "github.com/wealdtech/ethdo/util" 22 | ) 23 | 24 | func TestBaseDir(t *testing.T) { 25 | tests := []struct { 26 | name string 27 | inputs map[string]interface{} 28 | expected string 29 | }{ 30 | { 31 | name: "Nil", 32 | }, 33 | { 34 | name: "Current", 35 | inputs: map[string]interface{}{ 36 | "base-dir": "/tmp", 37 | }, 38 | expected: "/tmp", 39 | }, 40 | { 41 | name: "Deprecated", 42 | inputs: map[string]interface{}{ 43 | "basedir": "/tmp", 44 | }, 45 | expected: "/tmp", 46 | }, 47 | { 48 | name: "Override", 49 | inputs: map[string]interface{}{ 50 | "basedir": "/tmp", 51 | "base-dir": "/tmp2", 52 | }, 53 | expected: "/tmp2", 54 | }, 55 | } 56 | 57 | for _, test := range tests { 58 | t.Run(test.name, func(t *testing.T) { 59 | viper.Reset() 60 | for k, v := range test.inputs { 61 | viper.Set(k, v) 62 | } 63 | res := util.GetBaseDir() 64 | require.Equal(t, test.expected, res) 65 | }) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /util/bls.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util 15 | 16 | import ( 17 | "encoding/binary" 18 | 19 | "github.com/herumi/bls-eth-go-binary/bls" 20 | ) 21 | 22 | // BLSID turns a uint64 in to a BLS identifier. 23 | func BLSID(id uint64) *bls.ID { 24 | var res bls.ID 25 | buf := [8]byte{} 26 | binary.LittleEndian.PutUint64(buf[:], id) 27 | if err := res.SetLittleEndian(buf[:]); err != nil { 28 | panic(err) 29 | } 30 | return &res 31 | } 32 | -------------------------------------------------------------------------------- /util/bls_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/require" 20 | "github.com/wealdtech/ethdo/util" 21 | e2types "github.com/wealdtech/go-eth2-types/v2" 22 | ) 23 | 24 | func TestBLSID(t *testing.T) { 25 | require.NoError(t, e2types.InitBLS()) 26 | 27 | tests := []struct { 28 | name string 29 | in uint64 30 | strRes string 31 | }{ 32 | { 33 | name: "Zero", 34 | in: 0, 35 | strRes: "0", 36 | }, 37 | { 38 | name: "One", 39 | in: 1, 40 | strRes: "1", 41 | }, 42 | { 43 | name: "High", 44 | in: 0x7fffffff, 45 | strRes: "2147483647", 46 | }, 47 | } 48 | 49 | for _, test := range tests { 50 | t.Run(test.name, func(t *testing.T) { 51 | blsID := util.BLSID(test.in) 52 | require.Equal(t, test.strRes, blsID.GetDecString()) 53 | }) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /util/epoch.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util 15 | 16 | import ( 17 | "context" 18 | "strconv" 19 | 20 | "github.com/attestantio/go-eth2-client/spec/phase0" 21 | "github.com/pkg/errors" 22 | "github.com/wealdtech/ethdo/services/chaintime" 23 | ) 24 | 25 | // ParseEpoch parses input to calculate the desired epoch. 26 | func ParseEpoch(_ context.Context, chainTime chaintime.Service, epochStr string) (phase0.Epoch, error) { 27 | currentEpoch := chainTime.CurrentEpoch() 28 | switch epochStr { 29 | case "", "current", "head", "-0": 30 | return currentEpoch, nil 31 | case "last": 32 | if currentEpoch > 0 { 33 | currentEpoch-- 34 | } 35 | return currentEpoch, nil 36 | default: 37 | val, err := strconv.ParseInt(epochStr, 10, 64) 38 | if err != nil { 39 | return 0, errors.Wrap(err, "failed to parse epoch") 40 | } 41 | if val >= 0 { 42 | return phase0.Epoch(val), nil 43 | } 44 | if phase0.Epoch(-val) > currentEpoch { 45 | return 0, nil 46 | } 47 | return currentEpoch + phase0.Epoch(val), nil 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /util/networks_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/stretchr/testify/require" 20 | "github.com/wealdtech/ethdo/testutil" 21 | ) 22 | 23 | func TestNetworksInternal(t *testing.T) { 24 | tests := []struct { 25 | name string 26 | address []byte 27 | expected string 28 | }{ 29 | { 30 | name: "Empty", 31 | expected: "Unknown", 32 | }, 33 | { 34 | name: "Unknown", 35 | address: testutil.HexToBytes("0000000000000000000000000000000000000000"), 36 | expected: "Unknown", 37 | }, 38 | { 39 | name: "Mainnet", 40 | address: testutil.HexToBytes("00000000219ab540356cbb839cbe05303d7705fa"), 41 | expected: "Mainnet", 42 | }, 43 | { 44 | name: "Pyrmont", 45 | address: testutil.HexToBytes("8c5fecdc472e27bc447696f431e425d02dd46a8c"), 46 | expected: "Pyrmont", 47 | }, 48 | } 49 | 50 | for _, test := range tests { 51 | t.Run(test.name, func(t *testing.T) { 52 | require.Equal(t, test.expected, network(test.address)) 53 | }) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /util/passphrase.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util 15 | 16 | import ( 17 | zxcvbn "github.com/nbutton23/zxcvbn-go" 18 | "github.com/spf13/viper" 19 | ) 20 | 21 | // minPassphraseScore is the minimum acceptable passphrase score. 22 | const minPassphraseScore = 2 23 | 24 | // AcceptablePassphrase returns true if the passphrase is acceptable. 25 | func AcceptablePassphrase(passphrase string) bool { 26 | if viper.GetBool("allow-weak-passphrases") { 27 | return true 28 | } 29 | res := zxcvbn.PasswordStrength(passphrase, nil) 30 | return res.Score >= minPassphraseScore 31 | } 32 | -------------------------------------------------------------------------------- /util/passphrase_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util_test 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/spf13/viper" 20 | "github.com/stretchr/testify/require" 21 | "github.com/wealdtech/ethdo/util" 22 | ) 23 | 24 | func TestAcceptablePassphrase(t *testing.T) { 25 | tests := []struct { 26 | name string 27 | input string 28 | allowWeak bool 29 | expected bool 30 | }{ 31 | { 32 | name: "Empty", 33 | input: ``, 34 | expected: false, 35 | }, 36 | { 37 | name: "Simple", 38 | input: `password`, 39 | expected: false, 40 | }, 41 | { 42 | name: "AllowedWeak", 43 | input: `password`, 44 | allowWeak: true, 45 | expected: true, 46 | }, 47 | { 48 | name: "Complex", 49 | input: `Hu[J"yKH{z&-;[]'7T*Dm1:t`, 50 | expected: true, 51 | }, 52 | } 53 | 54 | for _, test := range tests { 55 | t.Run(test.name, func(t *testing.T) { 56 | viper.Set("allow-weak-passphrases", test.allowWeak) 57 | require.Equal(t, test.expected, util.AcceptablePassphrase(test.input)) 58 | }) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /util/slot.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 Weald Technology Trading 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util 15 | 16 | import ( 17 | "context" 18 | "strconv" 19 | 20 | "github.com/attestantio/go-eth2-client/spec/phase0" 21 | "github.com/pkg/errors" 22 | "github.com/wealdtech/ethdo/services/chaintime" 23 | ) 24 | 25 | // ParseSlot parses input to calculate the desired slot. 26 | func ParseSlot(_ context.Context, chainTime chaintime.Service, slotStr string) (phase0.Slot, error) { 27 | currentSlot := chainTime.CurrentSlot() 28 | switch slotStr { 29 | case "", "current", "head", "-0": 30 | return currentSlot, nil 31 | case "last": 32 | if currentSlot > 0 { 33 | currentSlot-- 34 | } 35 | return currentSlot, nil 36 | default: 37 | val, err := strconv.ParseInt(slotStr, 10, 64) 38 | if err != nil { 39 | return 0, errors.Wrap(err, "failed to parse slot") 40 | } 41 | if val >= 0 { 42 | return phase0.Slot(val), nil 43 | } 44 | if phase0.Slot(-val) > currentSlot { 45 | return 0, nil 46 | } 47 | return currentSlot + phase0.Slot(val), nil 48 | } 49 | } 50 | --------------------------------------------------------------------------------