From 0055cbc99c579548bbccf288c096af2af6b20838 Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Thu, 26 Sep 2024 18:12:41 -0700 Subject: [PATCH 1/5] feat: remove backend API deps for show cmd --- .github/workflows/release.yml | 5 +- .goreleaser.yml | 3 - go.mod | 2 +- go.sum | 7 +- pkg/rewards/show.go | 327 +++++++++++++++++----------------- pkg/rewards/types.go | 55 ++---- 6 files changed, 184 insertions(+), 215 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a2c14b1..81570e2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,4 @@ jobs: env: #https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TELEMETRY_TOKEN: ${{ secrets.TELEMETRY_TOKEN }} - EIGENLAYER_BACKEND_MAINNET_URL: ${{ secrets.EIGENLAYER_BACKEND_MAINNET_URL }} - EIGENLAYER_BACKEND_TESTNET_URL: ${{ secrets.EIGENLAYER_BACKEND_TESTNET_URL }} - EIGENLAYER_BACKEND_PREPROD_URL: ${{ secrets.EIGENLAYER_BACKEND_PREPROD_URL }} \ No newline at end of file + TELEMETRY_TOKEN: ${{ secrets.TELEMETRY_TOKEN }} \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml index b6318d1..af799f4 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -11,9 +11,6 @@ builds: - -X 'main.version={{.Version}}' - -X 'github.com/Layr-Labs/eigenlayer-cli/pkg/telemetry.telemetryToken={{ .Env.TELEMETRY_TOKEN }}' - -X 'github.com/Layr-Labs/eigenlayer-cli/pkg/telemetry.version={{.Version}}' - - -X 'github.com/Layr-Labs/eigenlayer-cli/pkg/rewards.preprodUrl={{.Env.EIGENLAYER_BACKEND_PREPROD_URL}}' - - -X 'github.com/Layr-Labs/eigenlayer-cli/pkg/rewards.mainnetUrl={{.Env.EIGENLAYER_BACKEND_MAINNET_URL}}' - - -X 'github.com/Layr-Labs/eigenlayer-cli/pkg/rewards.testnetUrl={{.Env.EIGENLAYER_BACKEND_TESTNET_URL}}' # windows is ignored by default, as the `goos` field by default only # contains linux and darwin env: diff --git a/go.mod b/go.mod index 4129fdb..1559405 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Layr-Labs/eigenlayer-contracts v0.3.2-mainnet-rewards github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12 github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e - github.com/Layr-Labs/eigensdk-go v0.1.11 + github.com/Layr-Labs/eigensdk-go v0.1.13-0.20240927005004-ed4b05c87610 github.com/blang/semver/v4 v4.0.0 github.com/consensys/gnark-crypto v0.12.1 github.com/ethereum/go-ethereum v1.14.5 diff --git a/go.sum b/go.sum index e7085ef..a58cf60 100644 --- a/go.sum +++ b/go.sum @@ -12,8 +12,9 @@ github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12 h1:G5Q1SnLmFbEjhOkky3vIHk github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12/go.mod h1:OlJd1QjqEW53wfWG/lJyPCGvrXwWVEjPQsP4TV+gttQ= github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e h1:DvW0/kWHV9mZsbH2KOjEHKTSIONNPUj6X05FJvUohy4= github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e/go.mod h1:T7tYN8bTdca2pkMnz9G2+ZwXYWw5gWqQUIu4KLgC/vM= -github.com/Layr-Labs/eigensdk-go v0.1.11 h1:ZTOPKGoOyzKfi7DbYI2azMECcjmK2sRtHoPpjCq1MBc= github.com/Layr-Labs/eigensdk-go v0.1.11/go.mod h1:XcLVDtlB1vOPj63D236b451+SC75B8gwgkpNhYHSxNs= +github.com/Layr-Labs/eigensdk-go v0.1.13-0.20240927005004-ed4b05c87610 h1:lGy4uSImJyOiaM8vSx0CEbsL3rbVfw0uEIuhGey/ubc= +github.com/Layr-Labs/eigensdk-go v0.1.13-0.20240927005004-ed4b05c87610/go.mod h1:bA21qMfmUFZcUe+a1RsDeOGm25xZO802Kfll2GlS8Us= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= @@ -134,8 +135,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE= -github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= +github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= diff --git a/pkg/rewards/show.go b/pkg/rewards/show.go index c306bdf..5873262 100644 --- a/pkg/rewards/show.go +++ b/pkg/rewards/show.go @@ -1,14 +1,12 @@ package rewards import ( - "bytes" "encoding/json" "errors" "fmt" - "sort" - "math/big" "net/http" + "sort" "strings" "github.com/Layr-Labs/eigenlayer-cli/pkg/internal/common" @@ -16,28 +14,25 @@ import ( "github.com/Layr-Labs/eigenlayer-cli/pkg/telemetry" "github.com/Layr-Labs/eigenlayer-cli/pkg/utils" + "github.com/Layr-Labs/eigenlayer-rewards-proofs/pkg/proofDataFetcher/httpProofDataFetcher" + + "github.com/Layr-Labs/eigensdk-go/chainio/clients/elcontracts" "github.com/Layr-Labs/eigensdk-go/logging" + eigenSdkUtils "github.com/Layr-Labs/eigensdk-go/utils" + "github.com/ethereum/go-ethereum/accounts/abi/bind" gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" "github.com/urfave/cli/v2" ) -var ( - preprodUrl = "" - testnetUrl = "" - mainnetUrl = "" -) - type ClaimType string const ( All ClaimType = "all" Unclaimed ClaimType = "unclaimed" Claimed ClaimType = "claimed" - - GetClaimableRewardsEndpoint = "grpc/eigenlayer.RewardsService/GetClaimableRewards" - GetEarnedTokensForStrategyEndpoint = "grpc/eigenlayer.RewardsService/GetEarnedTokensForStrategy" ) func ShowCmd(p utils.Prompter) *cli.Command { @@ -64,12 +59,14 @@ func getShowFlags() []cli.Flag { baseFlags := []cli.Flag{ &flags.NetworkFlag, &flags.OutputFileFlag, + &flags.OutputTypeFlag, &flags.VerboseFlag, + &flags.ETHRpcUrlFlag, &EarnerAddressFlag, - &NumberOfDaysFlag, &AVSAddressesFlag, &EnvironmentFlag, &ClaimTypeFlag, + &ProofStoreBaseURLFlag, } sort.Sort(cli.FlagsByName(baseFlags)) @@ -77,6 +74,7 @@ func getShowFlags() []cli.Flag { } func ShowRewards(cCtx *cli.Context) error { + ctx := cCtx.Context logger := common.GetLogger(cCtx) config, err := readAndValidateConfig(cCtx, logger) @@ -85,186 +83,192 @@ func ShowRewards(cCtx *cli.Context) error { } cCtx.App.Metadata["network"] = config.ChainID.String() - url := testnetUrl - if config.Environment == "mainnet" { - url = mainnetUrl - } else if config.Environment == "preprod" { - url = preprodUrl + ethClient, err := ethclient.Dial(config.RPCUrl) + if err != nil { + return eigenSdkUtils.WrapError("failed to create new eth client", err) } - if config.ClaimType == All { - requestBody := map[string]string{ - "earnerAddress": config.EarnerAddress.String(), - "days": fmt.Sprintf("%d", absInt64(config.NumberOfDays)), - } - resp, err := post( - fmt.Sprintf("%s/%s", url, GetEarnedTokensForStrategyEndpoint), - requestBody, - ) - if err != nil { - return err - } - defer resp.Body.Close() + elReader, err := elcontracts.NewReaderFromConfig( + elcontracts.Config{ + RewardsCoordinatorAddress: config.RewardsCoordinatorAddress, + }, + ethClient, logger, + ) + if err != nil { + return eigenSdkUtils.WrapError("failed to create new reader from config", err) + } + + df := httpProofDataFetcher.NewHttpProofDataFetcher( + config.ProofStoreBaseURL, + config.Environment, + config.Network, + http.DefaultClient, + ) - var responseBody RewardResponse - err = json.NewDecoder(resp.Body).Decode(&responseBody) + claimDate, _, err := getClaimDistributionRoot(ctx, "latest_active", elReader, logger) + if err != nil { + return eigenSdkUtils.WrapError("failed to get claim distribution root", err) + } + + proofData, err := df.FetchClaimAmountsForDate(ctx, claimDate) + if err != nil { + return eigenSdkUtils.WrapError("failed to fetch claim amounts for date", err) + } + + tokenAddressesMap, present := proofData.Distribution.GetTokensForEarner(config.EarnerAddress) + if !present { + return eigenSdkUtils.WrapError("earner address not found in distribution", nil) + } + + allRewards := make(map[gethcommon.Address]*big.Int) + for pair := tokenAddressesMap.Oldest(); pair != nil; pair = pair.Next() { + amt, _ := new(big.Int).SetString(pair.Value.String(), 10) + allRewards[pair.Key] = amt + } + + if config.ClaimType == All { + fmt.Println(strings.Repeat("-", 30), "All Rewards", strings.Repeat("-", 30)) + err := handleRewardsOutput(config.Output, config.OutputType, allRewards) if err != nil { return err } - normalizedRewards := normalizeRewardResponse(responseBody) - if common.IsEmptyString(config.Output) { - printNormalizedRewardsAsTable(normalizedRewards) - } else { - logger.Debugf("Writing total rewards to %s", config.Output) - err = common.WriteToCSV(normalizedRewards, config.Output) + } else { + claimedRewards := make(map[gethcommon.Address]*big.Int) + for address, _ := range allRewards { + claimed, err := elReader.GetCumulativeClaimed(&bind.CallOpts{Context: ctx}, config.EarnerAddress, address) if err != nil { return err } - logger.Infof("Total rewards written to %s", config.Output) - } - } else if config.ClaimType == Unclaimed { - requestBody := map[string]string{ - "earnerAddress": config.EarnerAddress.String(), + if claimed == nil { + claimed = big.NewInt(0) + } + claimedRewards[address] = claimed } - claimableRewardsUrl := fmt.Sprintf("%s/%s", url, GetClaimableRewardsEndpoint) - resp, err := post(claimableRewardsUrl, requestBody) - if err != nil { - return err + if config.ClaimType == Claimed { + fmt.Println(strings.Repeat("-", 30), "Claimed Rewards", strings.Repeat("-", 30)) + err := handleRewardsOutput(config.Output, config.OutputType, claimedRewards) + if err != nil { + return err + } + } else if config.ClaimType == Unclaimed { + unclaimedRewards := make(map[gethcommon.Address]*big.Int) + for address, _ := range allRewards { + total := allRewards[address] + claimed := claimedRewards[address] + unclaimedRewards[address] = new(big.Int).Sub(total, claimed) + } + fmt.Println(strings.Repeat("-", 30), "Unclaimed Rewards", strings.Repeat("-", 30)) + err := handleRewardsOutput(config.Output, config.OutputType, unclaimedRewards) + if err != nil { + return err + } + } else { + return fmt.Errorf("claim type %s not supported", config.ClaimType) } - defer resp.Body.Close() + } + + return nil +} - var response UnclaimedRewardResponse - err = json.NewDecoder(resp.Body).Decode(&response) +func handleRewardsOutput(outputFile string, outputType string, rewards map[gethcommon.Address]*big.Int) error { + if outputType == "json" { + allRewards := make(allRewardsJson, 0) + for address, amount := range rewards { + allRewards = append(allRewards, rewardsJson{ + Address: address.Hex(), + Amount: amount.String(), + }) + } + out, err := json.MarshalIndent(allRewards, "", " ") if err != nil { return err } - unclaimedNormalizedRewards := normalizeUnclaimedRewardResponse(response) - if common.IsEmptyString(config.Output) { - printUnclaimedNormalizedRewardsAsTable(unclaimedNormalizedRewards) + if outputFile != "" { + return common.WriteToFile(out, outputFile) } else { - logger.Debugf("Writing unclaimed rewards to %s", config.Output) - err = common.WriteToCSV(unclaimedNormalizedRewards, config.Output) - if err != nil { - return err - } - logger.Infof("Unclaimed rewards written to %s", config.Output) + fmt.Println(string(out)) } } else { - return fmt.Errorf("claim type %s not supported", config.ClaimType) + printRewards(rewards) } - return nil } -func post(url string, requestBody map[string]string) (*http.Response, error) { - jsonData, err := json.Marshal(requestBody) - if err != nil { - return nil, err +func printRewards(rewards map[gethcommon.Address]*big.Int) { + // Define column headers and widths + headers := []string{ + "Token Address", + "Amount (Wei)", } - return http.Post(url, "application/json", bytes.NewBuffer(jsonData)) -} + widths := []int{46, 30} -func normalizeUnclaimedRewardResponse(unclaimedRewardResponse UnclaimedRewardResponse) []NormalizedUnclaimedReward { - var normalizedUnclaimedRewards []NormalizedUnclaimedReward - for _, rewardsPerAVS := range unclaimedRewardResponse.Rewards { - for _, token := range rewardsPerAVS.Tokens { - amount := new(big.Int) - amount.SetString(token.WeiAmount, 10) - normalizedUnclaimedRewards = append(normalizedUnclaimedRewards, NormalizedUnclaimedReward{ - TokenAddress: token.TokenAddress, - WeiAmount: amount, - }) - } + // print dashes + for _, width := range widths { + fmt.Print("+" + strings.Repeat("-", width+1)) } - return normalizedUnclaimedRewards -} + fmt.Println("+") -func normalizeRewardResponse(rewardResponse RewardResponse) []NormalizedReward { - var normalizedRewards []NormalizedReward - for _, reward := range rewardResponse.Rewards { - for _, rewardsPerAVS := range reward.RewardsPerStrategy { - for _, token := range rewardsPerAVS.Tokens { - amount := new(big.Int) - amount.SetString(token.WeiAmount, 10) - normalizedRewards = append(normalizedRewards, NormalizedReward{ - StrategyAddress: reward.StrategyAddress, - AVSAddress: rewardsPerAVS.AVSAddress, - TokenAddress: token.TokenAddress, - WeiAmount: amount, - }) - } - } + // Print header + for i, header := range headers { + fmt.Printf("| %-*s", widths[i], header) } - return normalizedRewards -} + fmt.Println("|") -func printUnclaimedNormalizedRewardsAsTable(normalizedRewards []NormalizedUnclaimedReward) { - column := formatColumns( - "Token Address", - common.MaxAddressLength, - ) + " | " + formatColumns( - "Wei Amount", - common.MaxAddressLength, - ) - fmt.Println(strings.Repeat("-", len(column))) - fmt.Println(column) - fmt.Println(strings.Repeat("-", len(column))) - for _, reward := range normalizedRewards { - if reward.WeiAmount.Cmp(big.NewInt(0)) == 0 { - continue - } - fmt.Printf( - "%s | %s\n", - reward.TokenAddress, - reward.WeiAmount.String(), - ) + // Print separator + for _, width := range widths { + fmt.Print("|", strings.Repeat("-", width+1)) } - fmt.Println(strings.Repeat("-", len(column))) -} + fmt.Println("|") -func printNormalizedRewardsAsTable(normalizedRewards []NormalizedReward) { - column := formatColumns( - "Strategy Address", - common.MaxAddressLength, - ) + " | " + formatColumns( - "AVS Address", - common.MaxAddressLength, - ) + " | " + formatColumns( - "Token Address", - common.MaxAddressLength, - ) + " | " + formatColumns( - "Wei Amount", - common.MaxAddressLength, - ) - fmt.Println(strings.Repeat("-", len(column))) - fmt.Println(column) - fmt.Println(strings.Repeat("-", len(column))) - for _, reward := range normalizedRewards { - fmt.Printf( - "%s | %s | %s | %s\n", - reward.StrategyAddress, - reward.AVSAddress, - reward.TokenAddress, - reward.WeiAmount.String(), + // Print data rows + for address, amount := range rewards { + fmt.Printf("| %-*s| %-*s|\n", + widths[0], address.Hex(), + widths[1], amount.String(), ) } - fmt.Println(strings.Repeat("-", len(column))) -} -func formatColumns(columnName string, size int32) string { - return fmt.Sprintf("%-*s", size, columnName) + // print dashes + for _, width := range widths { + fmt.Print("+" + strings.Repeat("-", width+1)) + } + fmt.Println("+") } func readAndValidateConfig(cCtx *cli.Context, logger logging.Logger) (*ShowConfig, error) { earnerAddress := gethcommon.HexToAddress(cCtx.String(EarnerAddressFlag.Name)) output := cCtx.String(flags.OutputFileFlag.Name) - numberOfDays := cCtx.Int64(NumberOfDaysFlag.Name) + outputType := cCtx.String(flags.OutputTypeFlag.Name) + ethRpcUrl := cCtx.String(flags.ETHRpcUrlFlag.Name) network := cCtx.String(flags.NetworkFlag.Name) env := cCtx.String(EnvironmentFlag.Name) if env == "" { env = getEnvFromNetwork(network) } logger.Debugf("Network: %s, Env: %s", network, env) + rewardsCoordinatorAddress := cCtx.String(RewardsCoordinatorAddressFlag.Name) + + var err error + if common.IsEmptyString(rewardsCoordinatorAddress) { + rewardsCoordinatorAddress, err = common.GetRewardCoordinatorAddress(utils.NetworkNameToChainId(network)) + if err != nil { + return nil, err + } + } + logger.Debugf("Using Rewards Coordinator address: %s", rewardsCoordinatorAddress) + + proofStoreBaseURL := cCtx.String(ProofStoreBaseURLFlag.Name) + + // If empty get from utils + if common.IsEmptyString(proofStoreBaseURL) { + proofStoreBaseURL = getProofStoreBaseURL(network) + + // If still empty return error + if common.IsEmptyString(proofStoreBaseURL) { + return nil, errors.New("proof store base URL not provided") + } + } + logger.Debugf("Using Proof store base URL: %s", proofStoreBaseURL) claimType := ClaimType(cCtx.String(ClaimTypeFlag.Name)) if claimType != All && claimType != Unclaimed && claimType != Claimed { @@ -275,20 +279,15 @@ func readAndValidateConfig(cCtx *cli.Context, logger logging.Logger) (*ShowConfi logger.Debugf("Using chain ID: %s", chainID.String()) return &ShowConfig{ - EarnerAddress: earnerAddress, - NumberOfDays: numberOfDays, - Network: network, - Environment: env, - ClaimType: claimType, - ChainID: chainID, - Output: output, + EarnerAddress: earnerAddress, + Network: network, + Environment: env, + ClaimType: claimType, + ChainID: chainID, + Output: output, + OutputType: outputType, + RPCUrl: ethRpcUrl, + ProofStoreBaseURL: proofStoreBaseURL, + RewardsCoordinatorAddress: gethcommon.HexToAddress(rewardsCoordinatorAddress), }, nil } - -// absInt64 returns the absolute value of an int64. -func absInt64(x int64) int64 { - if x < 0 { - return -x - } - return x -} diff --git a/pkg/rewards/types.go b/pkg/rewards/types.go index 6b0aa02..db774ad 100644 --- a/pkg/rewards/types.go +++ b/pkg/rewards/types.go @@ -7,41 +7,12 @@ import ( gethcommon "github.com/ethereum/go-ethereum/common" ) -type RewardResponse struct { - Rewards []Reward `json:"rewards"` +type rewardsJson struct { + Address string `json:"tokenAddress"` + Amount string `json:"amount"` } -type Reward struct { - StrategyAddress string `json:"strategyAddress"` - RewardsPerStrategy []RewardPerStrategy `json:"rewards"` -} - -type RewardPerStrategy struct { - AVSAddress string `json:"avsAddress"` - Tokens []Token `json:"tokens"` -} - -type Token struct { - TokenAddress string `json:"tokenAddress"` - WeiAmount string `json:"weiAmount"` -} - -type NormalizedReward struct { - StrategyAddress string `csv:"strategyAddress"` - AVSAddress string `csv:"avsAddress"` - TokenAddress string `csv:"tokenAddress"` - WeiAmount *big.Int `csv:"weiAmount"` -} - -type UnclaimedRewardResponse struct { - BlockHeight string `json:"blockHeight"` - Rewards []RewardPerStrategy `json:"rewards"` -} - -type NormalizedUnclaimedReward struct { - TokenAddress string `csv:"tokenAddress"` - WeiAmount *big.Int `csv:"weiAmount"` -} +type allRewardsJson []rewardsJson type ClaimConfig struct { Network string @@ -75,11 +46,15 @@ type SetClaimerConfig struct { } type ShowConfig struct { - EarnerAddress gethcommon.Address - NumberOfDays int64 - Network string - Environment string - ClaimType ClaimType - ChainID *big.Int - Output string + EarnerAddress gethcommon.Address + RPCUrl string + NumberOfDays int64 + Network string + Environment string + ClaimType ClaimType + ChainID *big.Int + Output string + OutputType string + ProofStoreBaseURL string + RewardsCoordinatorAddress gethcommon.Address } From 8e7821d220a563499d61c11c17ba89375f1d89bf Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Thu, 26 Sep 2024 18:18:27 -0700 Subject: [PATCH 2/5] update readme --- pkg/rewards/README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pkg/rewards/README.md b/pkg/rewards/README.md index f771af9..1f4c72d 100644 --- a/pkg/rewards/README.md +++ b/pkg/rewards/README.md @@ -131,15 +131,17 @@ DESCRIPTION: OPTIONS: - --avs-addresses value, -a value Comma seperated addresses of the AVS [$AVS_ADDRESSES] - --claim-type value, --ct value Type of claim you want to see. Can be 'all', 'unclaimed', or 'claimed' (default: "all") [$REWARDS_CLAIM_TYPE] - --earner-address value, --ea value Address of the earner [$REWARDS_EARNER_ADDRESS] - --environment value, --env value Environment to use. Currently supports 'preprod' ,'testnet' and 'prod'. If not provided, it will be inferred based on network [$ENVIRONMENT] - --network value, -n value Network to use. Currently supports 'holesky' and 'mainnet' (default: "holesky") [$NETWORK] - --number-of-days value, --nd value Number of past days to show rewards for. It should be negative. Only used for 'all' claim type (default: -21) [$REWARDS_NUMBER_OF_DAYS] - --output-file value, -o value Output file to write the data [$OUTPUT_FILE] - --verbose, -v Enable verbose logging (default: false) [$VERBOSE] - --help, -h show help + --avs-addresses value, -a value Comma seperated addresses of the AVS [$AVS_ADDRESSES] + --claim-type value, --ct value Type of claim you want to see. Can be 'all', 'unclaimed', or 'claimed' (default: "all") [$REWARDS_CLAIM_TYPE] + --earner-address value, --ea value Address of the earner [$REWARDS_EARNER_ADDRESS] + --environment value, --env value Environment to use. Currently supports 'preprod' ,'testnet' and 'prod'. If not provided, it will be inferred based on network [$ENVIRONMENT] + --eth-rpc-url value, -r value URL of the Ethereum RPC [$ETH_RPC_URL] + --network value, -n value Network to use. Currently supports 'holesky' and 'mainnet' (default: "holesky") [$NETWORK] + --output-file value, -o value Output file to write the data [$OUTPUT_FILE] + --output-type value, --ot value Output format of the command. One of 'pretty', 'json' or 'calldata' (default: "pretty") [$OUTPUT_TYPE] + --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] + --verbose, -v Enable verbose logging (default: false) [$VERBOSE] + --help, -h show help ``` ### Testnet Show all Rewards From 2e5c79a4008e116189f422e2baa14276743c683e Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Thu, 26 Sep 2024 18:22:18 -0700 Subject: [PATCH 3/5] update readme --- pkg/rewards/README.md | 1 - pkg/rewards/show.go | 1 - 2 files changed, 2 deletions(-) diff --git a/pkg/rewards/README.md b/pkg/rewards/README.md index 1f4c72d..e91da49 100644 --- a/pkg/rewards/README.md +++ b/pkg/rewards/README.md @@ -131,7 +131,6 @@ DESCRIPTION: OPTIONS: - --avs-addresses value, -a value Comma seperated addresses of the AVS [$AVS_ADDRESSES] --claim-type value, --ct value Type of claim you want to see. Can be 'all', 'unclaimed', or 'claimed' (default: "all") [$REWARDS_CLAIM_TYPE] --earner-address value, --ea value Address of the earner [$REWARDS_EARNER_ADDRESS] --environment value, --env value Environment to use. Currently supports 'preprod' ,'testnet' and 'prod'. If not provided, it will be inferred based on network [$ENVIRONMENT] diff --git a/pkg/rewards/show.go b/pkg/rewards/show.go index 5873262..477af76 100644 --- a/pkg/rewards/show.go +++ b/pkg/rewards/show.go @@ -63,7 +63,6 @@ func getShowFlags() []cli.Flag { &flags.VerboseFlag, &flags.ETHRpcUrlFlag, &EarnerAddressFlag, - &AVSAddressesFlag, &EnvironmentFlag, &ClaimTypeFlag, &ProofStoreBaseURLFlag, From 500b8dcbee2c0744543d872ec1af24c0a8015638 Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Fri, 27 Sep 2024 10:33:41 -0700 Subject: [PATCH 4/5] refactor --- pkg/rewards/show.go | 99 ++++++++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 37 deletions(-) diff --git a/pkg/rewards/show.go b/pkg/rewards/show.go index 477af76..95dea3f 100644 --- a/pkg/rewards/show.go +++ b/pkg/rewards/show.go @@ -1,6 +1,7 @@ package rewards import ( + "context" "encoding/json" "errors" "fmt" @@ -29,10 +30,18 @@ import ( type ClaimType string +type ELReader interface { + GetCumulativeClaimed(opts *bind.CallOpts, earnerAddress, tokenAddress gethcommon.Address) (*big.Int, error) +} + const ( All ClaimType = "all" Unclaimed ClaimType = "unclaimed" Claimed ClaimType = "claimed" + + AllRewards = "All Rewards" + UnclaimedRewards = "Unclaimed Rewards" + ClaimedRewards = "Claimed Rewards" ) func ShowCmd(p utils.Prompter) *cli.Command { @@ -120,56 +129,72 @@ func ShowRewards(cCtx *cli.Context) error { } allRewards := make(map[gethcommon.Address]*big.Int) + msg := AllRewards for pair := tokenAddressesMap.Oldest(); pair != nil; pair = pair.Next() { amt, _ := new(big.Int).SetString(pair.Value.String(), 10) allRewards[pair.Key] = amt } - if config.ClaimType == All { - fmt.Println(strings.Repeat("-", 30), "All Rewards", strings.Repeat("-", 30)) - err := handleRewardsOutput(config.Output, config.OutputType, allRewards) + if config.ClaimType != All { + claimedRewards, err := getClaimedRewards(ctx, elReader, config.EarnerAddress, allRewards) if err != nil { - return err + return eigenSdkUtils.WrapError("failed to get claimed rewards", err) } - } else { - claimedRewards := make(map[gethcommon.Address]*big.Int) - for address, _ := range allRewards { - claimed, err := elReader.GetCumulativeClaimed(&bind.CallOpts{Context: ctx}, config.EarnerAddress, address) - if err != nil { - return err - } - if claimed == nil { - claimed = big.NewInt(0) - } - claimedRewards[address] = claimed + switch config.ClaimType { + case Claimed: + allRewards = claimedRewards + msg = ClaimedRewards + case Unclaimed: + allRewards = calculateUnclaimedRewards(allRewards, claimedRewards) + msg = UnclaimedRewards } - if config.ClaimType == Claimed { - fmt.Println(strings.Repeat("-", 30), "Claimed Rewards", strings.Repeat("-", 30)) - err := handleRewardsOutput(config.Output, config.OutputType, claimedRewards) - if err != nil { - return err - } - } else if config.ClaimType == Unclaimed { - unclaimedRewards := make(map[gethcommon.Address]*big.Int) - for address, _ := range allRewards { - total := allRewards[address] - claimed := claimedRewards[address] - unclaimedRewards[address] = new(big.Int).Sub(total, claimed) - } - fmt.Println(strings.Repeat("-", 30), "Unclaimed Rewards", strings.Repeat("-", 30)) - err := handleRewardsOutput(config.Output, config.OutputType, unclaimedRewards) - if err != nil { - return err - } - } else { - return fmt.Errorf("claim type %s not supported", config.ClaimType) + } + err = handleRewardsOutput(config.Output, config.OutputType, allRewards, msg) + if err != nil { + return err + } + return nil +} + +func getClaimedRewards( + ctx context.Context, + elReader ELReader, + earnerAddress gethcommon.Address, + allRewards map[gethcommon.Address]*big.Int, +) (map[gethcommon.Address]*big.Int, error) { + claimedRewards := make(map[gethcommon.Address]*big.Int) + for address := range allRewards { + claimed, err := elReader.GetCumulativeClaimed(&bind.CallOpts{Context: ctx}, earnerAddress, address) + if err != nil { + return nil, err } + if claimed == nil { + claimed = big.NewInt(0) + } + claimedRewards[address] = claimed } + return claimedRewards, nil +} - return nil +func calculateUnclaimedRewards( + allRewards, + claimedRewards map[gethcommon.Address]*big.Int, +) map[gethcommon.Address]*big.Int { + unclaimedRewards := make(map[gethcommon.Address]*big.Int) + for address, total := range allRewards { + claimed := claimedRewards[address] + unclaimedRewards[address] = new(big.Int).Sub(total, claimed) + } + return unclaimedRewards } -func handleRewardsOutput(outputFile string, outputType string, rewards map[gethcommon.Address]*big.Int) error { +func handleRewardsOutput( + outputFile string, + outputType string, + rewards map[gethcommon.Address]*big.Int, + msg string, +) error { + fmt.Println(strings.Repeat("-", 30), msg, strings.Repeat("-", 30)) if outputType == "json" { allRewards := make(allRewardsJson, 0) for address, amount := range rewards { From 7e477db57d52755f9cb94a8aa2aff7e662752edc Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Fri, 27 Sep 2024 10:35:17 -0700 Subject: [PATCH 5/5] refactor --- pkg/rewards/show.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/pkg/rewards/show.go b/pkg/rewards/show.go index 95dea3f..be2936a 100644 --- a/pkg/rewards/show.go +++ b/pkg/rewards/show.go @@ -38,10 +38,6 @@ const ( All ClaimType = "all" Unclaimed ClaimType = "unclaimed" Claimed ClaimType = "claimed" - - AllRewards = "All Rewards" - UnclaimedRewards = "Unclaimed Rewards" - ClaimedRewards = "Claimed Rewards" ) func ShowCmd(p utils.Prompter) *cli.Command { @@ -129,7 +125,7 @@ func ShowRewards(cCtx *cli.Context) error { } allRewards := make(map[gethcommon.Address]*big.Int) - msg := AllRewards + msg := "All Rewards" for pair := tokenAddressesMap.Oldest(); pair != nil; pair = pair.Next() { amt, _ := new(big.Int).SetString(pair.Value.String(), 10) allRewards[pair.Key] = amt @@ -143,10 +139,10 @@ func ShowRewards(cCtx *cli.Context) error { switch config.ClaimType { case Claimed: allRewards = claimedRewards - msg = ClaimedRewards + msg = "Claimed Rewards" case Unclaimed: allRewards = calculateUnclaimedRewards(allRewards, claimedRewards) - msg = UnclaimedRewards + msg = "Unclaimed Rewards" } } err = handleRewardsOutput(config.Output, config.OutputType, allRewards, msg)