Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for fireblocks wallet #115

Merged
merged 9 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading