Skip to content

Commit

Permalink
Merge pull request #10 from bcdevtools/imp/support-mnemonic-as-secret…
Browse files Browse the repository at this point in the history
…-key

imp: support mnemonic as account secret
  • Loading branch information
0xbcdev authored Jan 22, 2025
2 parents 8bbd8f6 + 7d97653 commit fdce1bd
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 28 deletions.
34 changes: 23 additions & 11 deletions cmd/tx/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/ecdsa"
"fmt"
"os"
"regexp"
"strings"

"github.com/bcdevtools/devd/v2/cmd/utils"
Expand Down Expand Up @@ -64,17 +65,28 @@ func mustSecretEvmAccount(cmd *cobra.Command) (privKey string, ecdsaPrivateKey *
os.Exit(1)
}

privKey = strings.TrimPrefix(privKey, "0x")

pKeyBytes, err := hexutil.Decode("0x" + privKey)
if err != nil {
utils.PrintlnStdErr("ERR: failed to decode secret key")
os.Exit(1)
}

ecdsaPrivateKey, err = crypto.ToECDSA(pKeyBytes)
if err != nil {
utils.PrintlnStdErr("ERR: failed to convert secret key to ECDSA")
if regexp.MustCompile(`^(0x)?[a-fA-F\d]{64}$`).MatchString(privKey) {
// private key
privKey = strings.TrimPrefix(privKey, "0x")

pKeyBytes, err := hexutil.Decode("0x" + privKey)
if err != nil {
utils.PrintlnStdErr("ERR: failed to decode private key")
os.Exit(1)
}

ecdsaPrivateKey, err = crypto.ToECDSA(pKeyBytes)
if err != nil {
utils.PrintlnStdErr("ERR: failed to convert private key to ECDSA")
os.Exit(1)
}
} else if mnemonicCount := len(strings.Split(privKey, " ")); mnemonicCount == 12 || mnemonicCount == 24 {
// is mnemonic
mnemonic := privKey
ecdsaPrivateKey, err = utils.FromMnemonicToPrivateKey(mnemonic, "" /*no password protected*/)
utils.ExitOnErr(err, "failed to convert mnemonic to private key")
} else {
utils.PrintlnStdErr("ERR: invalid secret key format")
os.Exit(1)
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/tx/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const (

const (
flagEvmRpcDesc = "EVM Json-RPC endpoint, default is " + constants.DEFAULT_EVM_RPC + ", can be set by environment variable " + constants.ENV_EVM_RPC
flagSecretKeyDesc = "Secret key of the account, can be set by environment variable " + constants.ENV_SECRET_KEY
flagSecretKeyDesc = "Secret private key or mnemonic of the account, can be set by environment variable " + constants.ENV_SECRET_KEY
)

// Commands registers a sub-tree of commands
Expand Down
48 changes: 48 additions & 0 deletions cmd/utils/account_util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package utils

import (
"crypto/ecdsa"

"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/chaincfg"
cosmoshd "github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/go-bip39"
"github.com/ethereum/go-ethereum/accounts"
)

func FromMnemonicToPrivateKey(mnemonic, password string) (*ecdsa.PrivateKey, error) {
hdPathStr := cosmoshd.CreateHDPath(60, 0, 0).String()
hdPath, err := accounts.ParseDerivationPath(hdPathStr)
if err != nil {
return nil, err
}

seed, err := bip39.NewSeedWithErrorChecking(mnemonic, password)
if err != nil {
return nil, err
}

// create a BTC-utils hd-derivation key chain
masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
if err != nil {
return nil, err
}

key := masterKey
for _, n := range hdPath {
key, err = key.Derive(n)
if err != nil {
return nil, err
}
}

// btc-utils representation of a secp256k1 private key
privateKey, err := key.ECPrivKey()
if err != nil {
return nil, err
}

// cast private key to a convertible form (single scalar field element of secp256k1)
// and then load into ethcrypto private key format.
return privateKey.ToECDSA(), nil
}
13 changes: 9 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ module github.com/bcdevtools/devd/v2
go 1.20

require (
github.com/btcsuite/btcd v0.24.2
github.com/btcsuite/btcd/btcutil v1.1.5
github.com/cometbft/cometbft v0.37.4
github.com/cosmos/cosmos-sdk v0.47.10
github.com/cosmos/go-bip39 v1.0.0
github.com/ethereum/go-ethereum v1.10.26
github.com/pkg/errors v0.9.1
github.com/shirou/gopsutil/v3 v3.24.3
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb
)

Expand All @@ -20,6 +23,7 @@ require (
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cometbft/cometbft-db v0.7.0 // indirect
Expand All @@ -29,6 +33,7 @@ require (
github.com/cosmos/gogoproto v1.4.10 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
Expand Down Expand Up @@ -90,10 +95,10 @@ require (
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/bbolt v1.3.7 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/crypto v0.32.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect
google.golang.org/grpc v1.60.1 // indirect
google.golang.org/protobuf v1.32.0 // indirect
Expand Down
Loading

0 comments on commit fdce1bd

Please sign in to comment.