Skip to content

Commit

Permalink
add support for fireblocks wallet (#115)
Browse files Browse the repository at this point in the history
* add support for fireblocks wallet

* fix error

* debug error

* debug error

* debug error

* undo commit

* update deps

* update deps

* add timeout as config
  • Loading branch information
shrimalmadhur authored Apr 26, 2024
1 parent 433d322 commit daba4bb
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 78 deletions.
123 changes: 85 additions & 38 deletions pkg/operator/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,25 @@ import (
"math/big"
"os/user"
"strings"

eigensdkTypes "github.com/Layr-Labs/eigensdk-go/types"
eigenSdkUtils "github.com/Layr-Labs/eigensdk-go/utils"

"github.com/Layr-Labs/eigensdk-go/chainio/txmgr"
"github.com/Layr-Labs/eigensdk-go/signerv2"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"time"

"github.com/Layr-Labs/eigenlayer-cli/pkg/types"
"github.com/Layr-Labs/eigenlayer-cli/pkg/utils"

elContracts "github.com/Layr-Labs/eigensdk-go/chainio/clients/elcontracts"
"github.com/Layr-Labs/eigensdk-go/chainio/clients/eth"
"github.com/Layr-Labs/eigensdk-go/chainio/clients/fireblocks"
"github.com/Layr-Labs/eigensdk-go/chainio/clients/wallet"
"github.com/Layr-Labs/eigensdk-go/chainio/txmgr"
eigensdkLogger "github.com/Layr-Labs/eigensdk-go/logging"
"github.com/Layr-Labs/eigensdk-go/metrics"
"github.com/Layr-Labs/eigensdk-go/signerv2"
eigensdkTypes "github.com/Layr-Labs/eigensdk-go/types"
eigenSdkUtils "github.com/Layr-Labs/eigensdk-go/utils"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"

"github.com/urfave/cli/v2"
)

Expand Down Expand Up @@ -67,41 +69,12 @@ func RegisterCmd(p utils.Prompter) *cli.Command {
return err
}

// Check if input is available in the pipe and read the password from it
ecdsaPassword, readFromPipe := utils.GetStdInPassword()
if !readFromPipe {
ecdsaPassword, err = p.InputHiddenString("Enter password to decrypt the ecdsa private key:", "",
func(password string) error {
return nil
},
)
if err != nil {
fmt.Println("Error while reading ecdsa key password")
return err
}
}

// This is to expand the tilde in the path to the home directory
// This is not supported by Go's standard library
keyFullPath, err := expandTilde(operatorCfg.PrivateKeyStorePath)
keyWallet, sender, err := getWallet(operatorCfg, ethClient, p, logger)
if err != nil {
return err
}
operatorCfg.PrivateKeyStorePath = keyFullPath

signerCfg := signerv2.Config{
KeystorePath: operatorCfg.PrivateKeyStorePath,
Password: ecdsaPassword,
}
sgn, sender, err := signerv2.SignerFromConfig(signerCfg, &operatorCfg.ChainId)
if err != nil {
return err
}
privateKeyWallet, err := wallet.NewPrivateKeyWallet(ethClient, sgn, sender, logger)
if err != nil {
return err
}
txMgr := txmgr.NewSimpleTxManager(privateKeyWallet, ethClient, logger, sender)
txMgr := txmgr.NewSimpleTxManager(keyWallet, ethClient, logger, sender)

noopMetrics := metrics.NewNoopMetrics()

Expand Down Expand Up @@ -157,6 +130,80 @@ func RegisterCmd(p utils.Prompter) *cli.Command {
return registerCmd
}

func getWallet(
cfg *types.OperatorConfigNew,
ethClient eth.Client,
p utils.Prompter,
logger eigensdkLogger.Logger,
) (wallet.Wallet, common.Address, error) {
var keyWallet wallet.Wallet
if cfg.SignerType == types.LocalKeystoreSigner {
// Check if input is available in the pipe and read the password from it
ecdsaPassword, readFromPipe := utils.GetStdInPassword()
var err error
if !readFromPipe {
ecdsaPassword, err = p.InputHiddenString("Enter password to decrypt the ecdsa private key:", "",
func(password string) error {
return nil
},
)
if err != nil {
fmt.Println("Error while reading ecdsa key password")
return nil, common.Address{}, err
}
}

// This is to expand the tilde in the path to the home directory
// This is not supported by Go's standard library
keyFullPath, err := expandTilde(cfg.PrivateKeyStorePath)
if err != nil {
return nil, common.Address{}, err
}
cfg.PrivateKeyStorePath = keyFullPath

signerCfg := signerv2.Config{
KeystorePath: cfg.PrivateKeyStorePath,
Password: ecdsaPassword,
}
sgn, sender, err := signerv2.SignerFromConfig(signerCfg, &cfg.ChainId)
if err != nil {
return nil, common.Address{}, err
}
keyWallet, err = wallet.NewPrivateKeyWallet(ethClient, sgn, sender, logger)
if err != nil {
return nil, common.Address{}, err
}
return keyWallet, sender, nil
} else if cfg.SignerType == types.FireBlocksSigner {
fireblocksClient, err := fireblocks.NewClient(
cfg.FireblocksConfig.APIKey,
[]byte(cfg.FireblocksConfig.SecretKey),
cfg.FireblocksConfig.BaseUrl,
time.Duration(cfg.FireblocksConfig.Timeout)*time.Second,
logger,
)
if err != nil {
return nil, common.Address{}, err
}
keyWallet, err = wallet.NewFireblocksWallet(
fireblocksClient,
ethClient,
cfg.FireblocksConfig.VaultAccountName,
logger,
)
if err != nil {
return nil, common.Address{}, err
}
sender, err := keyWallet.SenderAddress(context.Background())
if err != nil {
return nil, common.Address{}, err
}
return keyWallet, sender, nil
} else {
return nil, common.Address{}, fmt.Errorf("%s signer is not supported", cfg.SignerType)
}
}

// expandTilde replaces the tilde (~) in the path with the home directory.
func expandTilde(path string) (string, error) {
if strings.HasPrefix(path, "~") {
Expand Down
48 changes: 12 additions & 36 deletions pkg/operator/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import (
"context"
"fmt"

"github.com/Layr-Labs/eigensdk-go/chainio/clients/wallet"
"github.com/Layr-Labs/eigensdk-go/chainio/txmgr"
"github.com/Layr-Labs/eigensdk-go/signerv2"

"github.com/Layr-Labs/eigenlayer-cli/pkg/utils"

elContracts "github.com/Layr-Labs/eigensdk-go/chainio/clients/elcontracts"
"github.com/Layr-Labs/eigensdk-go/chainio/clients/eth"
"github.com/Layr-Labs/eigensdk-go/chainio/txmgr"
eigensdkLogger "github.com/Layr-Labs/eigensdk-go/logging"
"github.com/Layr-Labs/eigensdk-go/metrics"

"github.com/ethereum/go-ethereum/common"

"github.com/urfave/cli/v2"
)

Expand Down Expand Up @@ -43,6 +43,12 @@ func UpdateCmd(p utils.Prompter) *cli.Command {
return err
}

fmt.Printf(
"\r%s Operator configuration file validated successfully %s\n",
utils.EmojiCheckMark,
operatorCfg.Operator.Address,
)

logger, err := eigensdkLogger.NewZapLogger(eigensdkLogger.Development)
if err != nil {
return err
Expand All @@ -53,42 +59,12 @@ func UpdateCmd(p utils.Prompter) *cli.Command {
return err
}

// Check if input is available in the pipe and read the password from it
ecdsaPassword, readFromPipe := utils.GetStdInPassword()
if !readFromPipe {
ecdsaPassword, err = p.InputHiddenString("Enter password to decrypt the ecdsa private key:", "",
func(password string) error {
return nil
},
)
if err != nil {
fmt.Println("Error while reading ecdsa key password")
return err
}
}

// This is to expand the tilde in the path to the home directory
// This is not supported by Go's standard library
keyFullPath, err := expandTilde(operatorCfg.PrivateKeyStorePath)
if err != nil {
return err
}
operatorCfg.PrivateKeyStorePath = keyFullPath

signerCfg := signerv2.Config{
KeystorePath: operatorCfg.PrivateKeyStorePath,
Password: ecdsaPassword,
}
sgn, sender, err := signerv2.SignerFromConfig(signerCfg, &operatorCfg.ChainId)
keyWallet, sender, err := getWallet(operatorCfg, ethClient, p, logger)
if err != nil {
return err
}

privateKeyWallet, err := wallet.NewPrivateKeyWallet(ethClient, sgn, sender, logger)
if err != nil {
return err
}
txMgr := txmgr.NewSimpleTxManager(privateKeyWallet, ethClient, logger, sender)
txMgr := txmgr.NewSimpleTxManager(keyWallet, ethClient, logger, sender)

noopMetrics := metrics.NewNoopMetrics()

Expand Down
20 changes: 16 additions & 4 deletions pkg/types/operator_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,28 @@ type SignerType string
const (
PrivateKeySigner SignerType = "private_key"
LocalKeystoreSigner SignerType = "local_keystore"
FireBlocksSigner SignerType = "fireblocks"
)

type FireblocksConfig struct {
APIKey string `yaml:"api_key"`
SecretKey string `yaml:"secret_key"`
BaseUrl string `yaml:"base_url"`
VaultAccountName string `yaml:"vault_account_name"`

// Timeout for API in seconds
Timeout int64 `yaml:"timeout"`
}

type OperatorConfigNew struct {
Operator eigensdkTypes.Operator `yaml:"operator"`
ELDelegationManagerAddress string `yaml:"el_delegation_manager_address"`
ELAVSDirectoryAddress string
EthRPCUrl string `yaml:"eth_rpc_url"`
PrivateKeyStorePath string `yaml:"private_key_store_path"`
SignerType SignerType `yaml:"signer_type"`
ChainId big.Int `yaml:"chain_id"`
EthRPCUrl string `yaml:"eth_rpc_url"`
PrivateKeyStorePath string `yaml:"private_key_store_path"`
SignerType SignerType `yaml:"signer_type"`
ChainId big.Int `yaml:"chain_id"`
FireblocksConfig FireblocksConfig `yaml:"fireblocks"`
}

func (config OperatorConfigNew) MarshalYAML() (interface{}, error) {
Expand Down

0 comments on commit daba4bb

Please sign in to comment.