diff --git a/pkg/common/flags/fireblocks.go b/pkg/common/flags/fireblocks.go new file mode 100644 index 0000000..c2a617e --- /dev/null +++ b/pkg/common/flags/fireblocks.go @@ -0,0 +1,63 @@ +package flags + +import "github.com/urfave/cli/v2" + +var ( + // FireblocksAPIKeyFlag is the flag to set the Fireblocks API key + FireblocksAPIKeyFlag = cli.StringFlag{ + Name: "fireblocks-api-key", + Aliases: []string{"ff"}, + Usage: "Fireblocks API key", + EnvVars: []string{"FIREBLOCKS_API_KEY"}, + } + + // FireblocksSecretKeyFlag is the flag to set the Fireblocks secret key + FireblocksSecretKeyFlag = cli.StringFlag{ + Name: "fireblocks-secret-key", + Aliases: []string{"fs"}, + Usage: "Fireblocks secret key. If you are using AWS Secret Manager, this should be the secret name.", + EnvVars: []string{"FIREBLOCKS_SECRET_KEY"}, + } + + // FireblocksBaseUrlFlag is the flag to set the Fireblocks base URL + FireblocksBaseUrlFlag = cli.StringFlag{ + Name: "fireblocks-base-url", + Aliases: []string{"fb"}, + Usage: "Fireblocks base URL", + EnvVars: []string{"FIREBLOCKS_BASE_URL"}, + } + + // FireblocksVaultAccountNameFlag is the flag to set the Fireblocks vault account name + FireblocksVaultAccountNameFlag = cli.StringFlag{ + Name: "fireblocks-vault-account-name", + Aliases: []string{"fv"}, + Usage: "Fireblocks vault account name", + EnvVars: []string{"FIREBLOCKS_VAULT_ACCOUNT_NAME"}, + } + + // FireblocksAWSRegionFlag is the flag to set the Fireblocks AWS region + FireblocksAWSRegionFlag = cli.StringFlag{ + Name: "fireblocks-aws-region", + Aliases: []string{"fa"}, + Usage: "AWS region if secret is stored in AWS KMS", + EnvVars: []string{"FIREBLOCKS_AWS_REGION"}, + Value: "us-east-1", + } + + // FireblocksTimeoutFlag is the flag to set the Fireblocks timeout + FireblocksTimeoutFlag = cli.Int64Flag{ + Name: "fireblocks-timeout", + Aliases: []string{"ft"}, + Usage: "Fireblocks timeout", + EnvVars: []string{"FIREBLOCKS_TIMEOUT"}, + Value: 30, + } + + // FireblocksSecretStorageTypeFlag is the flag to set the Fireblocks secret storage type + FireblocksSecretStorageTypeFlag = cli.StringFlag{ + Name: "fireblocks-secret-storage-type", + Aliases: []string{"fst"}, + Usage: "Fireblocks secret storage type. Supported values are 'plaintext' and 'aws_secret_manager'", + EnvVars: []string{"FIREBLOCKS_SECRET_STORAGE_TYPE"}, + } +) diff --git a/pkg/common/flags/general.go b/pkg/common/flags/general.go index 6443ad4..2b6c6f9 100644 --- a/pkg/common/flags/general.go +++ b/pkg/common/flags/general.go @@ -37,7 +37,7 @@ var ( PathToKeyStoreFlag = cli.StringFlag{ Name: "path-to-key-store", Aliases: []string{"k"}, - Usage: "Path to the key store", + Usage: "Path to the key store used to send transactions", EnvVars: []string{"PATH_TO_KEY_STORE"}, } diff --git a/pkg/common/flags/web3signer.go b/pkg/common/flags/web3signer.go new file mode 100644 index 0000000..d6b8c74 --- /dev/null +++ b/pkg/common/flags/web3signer.go @@ -0,0 +1,12 @@ +package flags + +import "github.com/urfave/cli/v2" + +var ( + Web3SignerUrlFlag = cli.StringFlag{ + Name: "web3signer-url", + Aliases: []string{"w"}, + Usage: "URL of the Web3Signer", + EnvVars: []string{"WEB3SIGNER_URL"}, + } +) diff --git a/pkg/common/helper.go b/pkg/common/helper.go index af6e170..4d269c3 100644 --- a/pkg/common/helper.go +++ b/pkg/common/helper.go @@ -3,6 +3,7 @@ package common import ( "context" "encoding/json" + "errors" "fmt" "math/big" "os/user" @@ -328,8 +329,7 @@ func validateMetadata(operatorCfg *types.OperatorConfig) error { func GetSignerConfig(cCtx *cli.Context, logger eigensdkLogger.Logger) (*types.SignerConfig, error) { ecdsaPrivateKeyString := cCtx.String(flags.EcdsaPrivateKeyFlag.Name) - pathToKeyStore := cCtx.String(flags.PathToKeyStoreFlag.Name) - if len(ecdsaPrivateKeyString) != 0 { + if !IsEmptyString(ecdsaPrivateKeyString) { logger.Debug("Using private key signer") pk, err := crypto.HexToECDSA(ecdsaPrivateKeyString) if err != nil { @@ -341,7 +341,8 @@ func GetSignerConfig(cCtx *cli.Context, logger eigensdkLogger.Logger) (*types.Si }, nil } - if len(pathToKeyStore) != 0 { + pathToKeyStore := cCtx.String(flags.PathToKeyStoreFlag.Name) + if !IsEmptyString(pathToKeyStore) { logger.Debug("Using local keystore signer") return &types.SignerConfig{ SignerType: types.LocalKeystoreSigner, @@ -349,5 +350,58 @@ func GetSignerConfig(cCtx *cli.Context, logger eigensdkLogger.Logger) (*types.Si }, nil } - return nil, fmt.Errorf("either ecdsa private key hex or path to keystore is required") + fireblocksAPIKey := cCtx.String(flags.FireblocksAPIKeyFlag.Name) + if !IsEmptyString(fireblocksAPIKey) { + logger.Debug("Using fireblocks signer") + fireblocksSecretKey := cCtx.String(flags.FireblocksSecretKeyFlag.Name) + if IsEmptyString(fireblocksSecretKey) { + return nil, errors.New("fireblocks secret key is required") + } + fireblocksVaultAccountName := cCtx.String(flags.FireblocksVaultAccountNameFlag.Name) + if IsEmptyString(fireblocksVaultAccountName) { + return nil, errors.New("fireblocks vault account name is required") + } + fireblocksBaseUrl := cCtx.String(flags.FireblocksBaseUrlFlag.Name) + if IsEmptyString(fireblocksBaseUrl) { + return nil, errors.New("fireblocks base url is required") + } + fireblocksTimeout := int64(cCtx.Int(flags.FireblocksTimeoutFlag.Name)) + if fireblocksTimeout <= 0 { + return nil, errors.New("fireblocks timeout should be greater than 0") + } + fireblocksSecretAWSRegion := cCtx.String(flags.FireblocksAWSRegionFlag.Name) + secretStorageType := cCtx.String(flags.FireblocksSecretStorageTypeFlag.Name) + if IsEmptyString(secretStorageType) { + return nil, errors.New("fireblocks secret storage type is required") + } + return &types.SignerConfig{ + SignerType: types.FireBlocksSigner, + FireblocksConfig: types.FireblocksConfig{ + APIKey: fireblocksAPIKey, + SecretKey: fireblocksSecretKey, + VaultAccountName: fireblocksVaultAccountName, + BaseUrl: fireblocksBaseUrl, + Timeout: fireblocksTimeout, + AWSRegion: fireblocksSecretAWSRegion, + SecretStorageType: types.SecretStorageType(secretStorageType), + }, + }, nil + } + + we3SignerUrl := cCtx.String(flags.Web3SignerUrlFlag.Name) + if !IsEmptyString(we3SignerUrl) { + logger.Debug("Using web3 signer") + return &types.SignerConfig{ + SignerType: types.Web3Signer, + Web3SignerConfig: types.Web3SignerConfig{ + Url: we3SignerUrl, + }, + }, nil + } + + return nil, fmt.Errorf("supported signer not found, please provide details for signers to use") +} + +func IsEmptyString(s string) bool { + return len(strings.TrimSpace(s)) == 0 } diff --git a/pkg/rewards/README.md b/pkg/rewards/README.md index 609aece..6c85193 100644 --- a/pkg/rewards/README.md +++ b/pkg/rewards/README.md @@ -10,20 +10,29 @@ USAGE: eigenlayer rewards claim [command options] OPTIONS: - --verbose, -v Enable verbose logging (default: false) [$VERBOSE] - --network value, -n value Network to use. Currently supports 'preprod', 'holesky' and 'mainnet' (default: "holesky") [$NETWORK] - --eth-rpc-url value, -r value URL of the Ethereum RPC [$ETH_RPC_URL] - --earner-address value, --ea value Address of the earner (this is your staker/operator address) [$EARNER_ADDRESS] - --output-file value, -o value Output file to write the data [$OUTPUT_FILE] - --path-to-key-store value, -k value Path to the key store [$PATH_TO_KEY_STORE] - --ecdsa-private-key value, -e value ECDSA private key hex to send transaction [$ECDSA_PRIVATE_KEY] - --broadcast, -b Use this flag to broadcast the transaction (default: false) [$BROADCAST] - --recipient-address value, --ra value Specify the address of the recipient. If this is not provided, the earner address will be used [$RECIPIENT_ADDRESS] - --token-addresses value, -t value Specify the addresses of the tokens to claim. Comma separated list of addresses [$TOKEN_ADDRESSES] - --rewards-coordinator-address value, --rc value Specify the address of the rewards coordinator. If not provided, the address will be used based on provided network [$REWARDS_COORDINATOR_ADDRESS] - --claim-timestamp value, -c value Specify the timestamp. Only 'latest' is supported (default: "latest") [$CLAIM_TIMESTAMP] - --proof-store-base-url value, --psbu value Specify the base URL of the proof store. If not provided, the value based on network will be used [$PROOF_STORE_BASE_URL] - --help, -h show help + --network value, -n value Network to use. Currently supports 'holesky' and 'mainnet' (default: "holesky") [$NETWORK] + --eth-rpc-url value, -r value URL of the Ethereum RPC [$ETH_RPC_URL] + --earner-address value, --ea value Address of the earner (this is your staker/operator address) [$EARNER_ADDRESS] + --output-file value, -o value Output file to write the data [$OUTPUT_FILE] + --broadcast, -b Use this flag to broadcast the transaction (default: false) [$BROADCAST] + --environment value, --env value Environment to use. Currently supports 'preprod' ,`testnet' and 'prod'. If not provided, it will be inferred based on network [$ENVIRONMENT] + --recipient-address value, --ra value Specify the address of the recipient. If this is not provided, the earner address will be used [$RECIPIENT_ADDRESS] + --token-addresses value, -t value Specify the addresses of the tokens to claim. Comma separated list of addresses [$TOKEN_ADDRESSES] + --rewards-coordinator-address value, --rc value Specify the address of the rewards coordinator. If not provided, the address will be used based on provided network [$REWARDS_COORDINATOR_ADDRESS] + --claim-timestamp value, -c value Specify the timestamp. Only 'latest' is supported (default: "latest") [$CLAIM_TIMESTAMP] + --proof-store-base-url value, --psbu value Specify the base URL of the proof store. If not provided, the value based on network will be used [$PROOF_STORE_BASE_URL] + --path-to-key-store value, -k value Path to the key store used to send transactions [$PATH_TO_KEY_STORE] + --ecdsa-private-key value, -e value ECDSA private key hex to send transaction [$ECDSA_PRIVATE_KEY] + --fireblocks-api-key value, --ff value Fireblocks API key [$FIREBLOCKS_API_KEY] + --fireblocks-secret-key value, --fs value Fireblocks secret key. If you are using AWS Secret Manager, this should be the secret name. [$FIREBLOCKS_SECRET_KEY] + --fireblocks-base-url value, --fb value Fireblocks base URL [$FIREBLOCKS_BASE_URL] + --fireblocks-vault-account-name value, --fv value Fireblocks vault account name [$FIREBLOCKS_VAULT_ACCOUNT_NAME] + --fireblocks-timeout value, --ft value Fireblocks timeout (default: 30) [$FIREBLOCKS_TIMEOUT] + --fireblocks-secret-storage-type value, --fst value Fireblocks secret storage type. Supported values are 'plaintext' and 'aws_secret_manager' [$FIREBLOCKS_SECRET_STORAGE_TYPE] + --fireblocks-aws-region value, --fa value AWS region if secret is stored in AWS KMS (default: "us-east-1") [$FIREBLOCKS_AWS_REGION] + --web3signer-url value, -w value URL of the Web3Signer [$WEB3SIGNER_URL] + --verbose, -v Enable verbose logging (default: false) [$VERBOSE] + --help, -h show help ``` #### Example @@ -67,17 +76,25 @@ DESCRIPTION: OPTIONS: - --verbose, -v Enable verbose logging (default: false) [$VERBOSE] - --network value, -n value Network to use. Currently supports 'holesky' and 'mainnet' (default: "holesky") [$NETWORK] - --eth-rpc-url value, -r value URL of the Ethereum RPC [$ETH_RPC_URL] - --earner-address value, --ea value Address of the earner (this is your staker/operator address) [$EARNER_ADDRESS] - --output-file value, -o value Output file to write the data [$OUTPUT_FILE] - --path-to-key-store value, -k value Path to the key store [$PATH_TO_KEY_STORE] - --ecdsa-private-key value, -e value ECDSA private key hex to send transaction [$ECDSA_PRIVATE_KEY] - --broadcast, -b Use this flag to broadcast the transaction (default: false) [$BROADCAST] - --rewards-coordinator-address value, --rc value Specify the address of the rewards coordinator. If not provided, the address will be used based on provided network [$REWARDS_COORDINATOR_ADDRESS] - --claimer-address value, -a value Address of the claimer [$NODE_OPERATOR_CLAIMER_ADDRESS] - --help, -h + --network value, -n value Network to use. Currently supports 'holesky' and 'mainnet' (default: "holesky") [$NETWORK] + --eth-rpc-url value, -r value URL of the Ethereum RPC [$ETH_RPC_URL] + --earner-address value, --ea value Address of the earner (this is your staker/operator address) [$EARNER_ADDRESS] + --output-file value, -o value Output file to write the data [$OUTPUT_FILE] + --broadcast, -b Use this flag to broadcast the transaction (default: false) [$BROADCAST] + --rewards-coordinator-address value, --rc value Specify the address of the rewards coordinator. If not provided, the address will be used based on provided network [$REWARDS_COORDINATOR_ADDRESS] + --claimer-address value, -a value Address of the claimer [$NODE_OPERATOR_CLAIMER_ADDRESS] + --path-to-key-store value, -k value Path to the key store used to send transactions [$PATH_TO_KEY_STORE] + --ecdsa-private-key value, -e value ECDSA private key hex to send transaction [$ECDSA_PRIVATE_KEY] + --fireblocks-api-key value, --ff value Fireblocks API key [$FIREBLOCKS_API_KEY] + --fireblocks-secret-key value, --fs value Fireblocks secret key. If you are using AWS Secret Manager, this should be the secret name. [$FIREBLOCKS_SECRET_KEY] + --fireblocks-base-url value, --fb value Fireblocks base URL [$FIREBLOCKS_BASE_URL] + --fireblocks-vault-account-name value, --fv value Fireblocks vault account name [$FIREBLOCKS_VAULT_ACCOUNT_NAME] + --fireblocks-timeout value, --ft value Fireblocks timeout (default: 30) [$FIREBLOCKS_TIMEOUT] + --fireblocks-secret-storage-type value, --fst value Fireblocks secret storage type. Supported values are 'plaintext' and 'aws_secret_manager' [$FIREBLOCKS_SECRET_STORAGE_TYPE] + --fireblocks-aws-region value, --fa value AWS region if secret is stored in AWS KMS (default: "us-east-1") [$FIREBLOCKS_AWS_REGION] + --web3signer-url value, -w value URL of the Web3Signer [$WEB3SIGNER_URL] + --verbose, -v Enable verbose logging (default: false) [$VERBOSE] + --help, -h show help ``` #### Example diff --git a/pkg/rewards/claim.go b/pkg/rewards/claim.go index 6161b5b..e1d09dc 100644 --- a/pkg/rewards/claim.go +++ b/pkg/rewards/claim.go @@ -60,13 +60,10 @@ func ClaimCmd(p utils.Prompter) *cli.Command { return Claim(cCtx, p) }, Flags: []cli.Flag{ - &flags.VerboseFlag, &flags.NetworkFlag, &flags.ETHRpcUrlFlag, &flags.EarnerAddressFlag, &flags.OutputFileFlag, - &flags.PathToKeyStoreFlag, - &flags.EcdsaPrivateKeyFlag, &flags.BroadcastFlag, &EnvironmentFlag, &RecipientAddressFlag, @@ -74,6 +71,17 @@ func ClaimCmd(p utils.Prompter) *cli.Command { &RewardsCoordinatorAddressFlag, &ClaimTimestampFlag, &ProofStoreBaseURLFlag, + &flags.PathToKeyStoreFlag, + &flags.EcdsaPrivateKeyFlag, + &flags.FireblocksAPIKeyFlag, + &flags.FireblocksSecretKeyFlag, + &flags.FireblocksBaseUrlFlag, + &flags.FireblocksVaultAccountNameFlag, + &flags.FireblocksTimeoutFlag, + &flags.FireblocksSecretStorageTypeFlag, + &flags.FireblocksAWSRegionFlag, + &flags.Web3SignerUrlFlag, + &flags.VerboseFlag, }, } diff --git a/pkg/rewards/setclaimer.go b/pkg/rewards/setclaimer.go index 1f82825..625c68b 100644 --- a/pkg/rewards/setclaimer.go +++ b/pkg/rewards/setclaimer.go @@ -46,16 +46,24 @@ Set the rewards claimer address for the earner. `, After: telemetry.AfterRunAction(), Flags: []cli.Flag{ - &flags.VerboseFlag, &flags.NetworkFlag, &flags.ETHRpcUrlFlag, &flags.EarnerAddressFlag, &flags.OutputFileFlag, - &flags.PathToKeyStoreFlag, - &flags.EcdsaPrivateKeyFlag, &flags.BroadcastFlag, &RewardsCoordinatorAddressFlag, &ClaimerAddressFlag, + &flags.PathToKeyStoreFlag, + &flags.EcdsaPrivateKeyFlag, + &flags.FireblocksAPIKeyFlag, + &flags.FireblocksSecretKeyFlag, + &flags.FireblocksBaseUrlFlag, + &flags.FireblocksVaultAccountNameFlag, + &flags.FireblocksTimeoutFlag, + &flags.FireblocksSecretStorageTypeFlag, + &flags.FireblocksAWSRegionFlag, + &flags.Web3SignerUrlFlag, + &flags.VerboseFlag, }, Action: func(cCtx *cli.Context) error { return SetClaimer(cCtx, p)