Skip to content
p2p-orgPublic

About

Dirk Key Converter

Resources

Stars

7 stars

Watchers

5 watching

Forks

Latest commit

 

History

89 Commits

Folders and files

Repository files navigation

Dirk Key Converter (dkc)

Go Report Card GitHub Workflow Status (with event)

A command-line tool for converting Ethereum wallets from:

to:

Caution

It is highly recommended to refrain from any operations on the validation keys and use the provided script only in critical situations to avoid any potential risks of slashing.

Table of Contents

Install

Binaries

Binaries for the latest version of dkc can be obtained from the releases page.

Verifying a release

dkc handles validator private key material, so it is worth checking that the archive you downloaded is the one the release workflow built. Every release archive is signed and carries build provenance.

The signature is keyless: there is no dkc public key to distribute, the signature is bound to the identity of the workflow that produced it. Each archive ships with a .cosign.bundle beside it, verified with cosign:

$ cosign verify-blob \
    --bundle dkc-<version>-linux-amd64.tar.gz.cosign.bundle \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com \
    --certificate-identity-regexp '^https://github\.com/p2p-org/dkc/' \
    dkc-<version>-linux-amd64.tar.gz

Build provenance — which workflow, commit and runner produced the archive — is attested to GitHub and checked with the gh CLI:

$ gh attestation verify dkc-<version>-linux-amd64.tar.gz --repo p2p-org/dkc

Releases also carry a CycloneDX SBOM (dkc-<version>.cdx.json) listing every Go module linked into the binaries, signed the same way.

Nix

If you have nix flakes enabled you can run dkc using this command:

$ nix run github:p2p-org/dkc

Source

dkc can be built locally using the command

$ go build .

Usage

Caution

Before you begin, make sure you backup keys and store recovered wallets and passwords securely.

dkc uses herumi/bls-eth-go-binary. You can test dkc on predefined inputs here.

Config

An example config for each pair could be found here

The example below shows how to convert wallets from distributed type to non-deterministic type (note: hierarchical deterministic can only be used as input - HD keys are derived from a mnemonic and cannot be imported).

base-dir for distributed wallets is located in ./i_wallet see more info about distributed wallet file structure here

base-dir for non-deterministic wallets is located in ./o_wallet see more info about non-deterministic wallet file structure here

input:                              #Input section
  store:                            #Store section
    path: ./i_wallet                #Location of input wallets
  wallet:                           #Wallet section
    type: distributed               #Type for input wallet. Valid types are: distributed, non-deterministic, hierarchical deterministic, keystore
    threshold: 2                    #Threshold number. It must be len(peers)/2 < threshold < len(peers) 
    peers:                          #Peers section
      10:                           #Peer ID is used for generating bls participants
        name: old1:9091             #Peer name is used for generating bls participants. All wallets for this peer are located in ./i_wallet/old1
        passphrases:                #Passphrases section
         path: ./peer1.txt          #Path to passphrases file(you can use separate passphrases file for each peer)
         index: 1                   #Password index in passphrases file. If not provided will use all passwords for unlocking wallets and only first password for creating accounts (Default: Using all passwords provided in passphrases file)
      20: 
        name: old2:9091
        passphrases: 
         path: ./peer2.txt
         index: 1
      30:
        name: old3:9091
        passphrases: 
         path: ./peer3.txt
         index: 1
output:                             #Output Wallet Section
  store:
    path: ./o_wallet
  wallet:
    type: non-deterministic         #Valid output types are: distributed, non-deterministic, keystore
    passphrases:
      path: ./o_passphrases.txt
log-level: debug                    #Log-level (Default: INFO)

File Structure

Distributed

This wallet type can be used as input or output wallet. More information about this wallet type is provided here

The following is an example file structure if one were to combine threshold keys. test1, test2, test3 are each the base-dir wallet directory from the dirk instance. test1, test2, test3 are each their own wallet directory.

ethdo wallet list --base-dir ./distributed-to-nd/distributed should return nothing.

The subdirectories of wallet folder are the actual ethdo wallets:

$ ethdo wallet list --base-dir distributed-to-nd/distributed/test1
Wallet2
Wallet3
Wallet1
$ ethdo wallet list --base-dir distributed-to-nd/distributed/test2
Wallet2
Wallet3
Wallet1
$ ethdo wallet list --base-dir distributed-to-nd/distributed/test3
Wallet1
Wallet2
Wallet3

Importantly, the names of each wallet folder must correspond with the values in *.wallet.peers defined in the config.

The keys within each wallet must also have the same name

All of the keys with corresponding names (ex: name = 1) should be the threshold keys corresponding to the same composite public key.

Hierarchical Deterministic

This wallet type can be used only as input wallet. More information about this wallet type is provided here

The following is an example file structure. The base-dir wallet directory is hd-to-distributed/hd

$ ethdo wallet --base-dir hd-to-distributed/hd list
Wallet1
Wallet3
Wallet2

Non-Deterministic

This wallet type can be used as input or output wallet. More information about this wallet type is provided here

The following is an example file structure. The base-dir wallet directory is nd-to-distributed/nd

$ ethdo wallet --base-dir nd-to-distributed/nd list
Wallet1
Wallet3
Wallet2

Keystore

This wallet type can be used as input or output wallet. More information about this wallet type is provided here

Keystore wallets store individual keys non-deterministically in keystore format. The file structure is similar to non-deterministic wallets:

$ ethdo wallet --base-dir keystore-to-distributed/keystore list
Wallet1
Wallet2
Wallet3

Configuration for keystore wallets:

input:
  store:
    path: ./keystore_wallet
  wallet:
    type: keystore
    passphrases:
      path: ./keystore_passwords.txt
      index: 0  # Optional: use specific password index

Convert

After preparing config and backing up keys simply run:

./dkc convert --config=config.yaml

Useful flags:

  • --log-level - overrides the config log level
  • --pprof - enables a profiling server on localhost:6060 (off by default)

Contribute

Contributions welcome. Please check out the issues.

License

License

About

Dirk Key Converter

Resources

Stars

7 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages