diff --git a/cmd/beacondeposit.go b/cmd/beacondeposit.go index cbccd06..14439a9 100644 --- a/cmd/beacondeposit.go +++ b/cmd/beacondeposit.go @@ -73,7 +73,7 @@ var beaconDepositKnownContracts = []*beaconDepositContract{ address: util.MustDecodeHexString("0x00000000219ab540356cBB839Cbe05303d7705Fa"), forkVersion: []byte{0x00, 0x00, 0x00, 0x00}, minVersion: 3, - maxVersion: 3, + maxVersion: 4, subgraph: "attestantio/eth2deposits", }, { @@ -82,7 +82,7 @@ var beaconDepositKnownContracts = []*beaconDepositContract{ address: util.MustDecodeHexString("0x6f22fFbC56eFF051aECF839396DD1eD9aD6BBA9D"), forkVersion: []byte{0x80, 0x00, 0x00, 0x69}, minVersion: 3, - maxVersion: 3, + maxVersion: 4, }, { network: "Prater", @@ -90,7 +90,7 @@ var beaconDepositKnownContracts = []*beaconDepositContract{ address: util.MustDecodeHexString("0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b"), forkVersion: []byte{0x00, 0x00, 0x10, 0x20}, minVersion: 3, - maxVersion: 3, + maxVersion: 4, subgraph: "attestantio/eth2deposits-prater", }, { @@ -99,7 +99,7 @@ var beaconDepositKnownContracts = []*beaconDepositContract{ address: util.MustDecodeHexString("0x4242424242424242424242424242424242424242"), forkVersion: []byte{0x70, 0x00, 0x00, 0x69}, minVersion: 3, - maxVersion: 3, + maxVersion: 4, }, { network: "Sepolia", @@ -107,7 +107,7 @@ var beaconDepositKnownContracts = []*beaconDepositContract{ address: util.MustDecodeHexString("0x7f02C3E3c98b133055B8B348B2Ac625669Ed295D"), forkVersion: []byte{0x90, 0x00, 0x00, 0x69}, minVersion: 3, - maxVersion: 3, + maxVersion: 4, }, } diff --git a/cmd/version.go b/cmd/version.go index 165231b..3ca1d79 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -30,7 +30,7 @@ var versionCmd = &cobra.Command{ ethereal version.`, Run: func(cmd *cobra.Command, args []string) { - fmt.Println("2.8.4") + fmt.Println("2.8.5") if viper.GetBool("verbose") { buildInfo, ok := dbg.ReadBuildInfo() if ok { diff --git a/util/depositinfo.go b/util/depositinfo.go index b2ec537..aa57c53 100644 --- a/util/depositinfo.go +++ b/util/depositinfo.go @@ -89,6 +89,18 @@ type depositInfoCLI struct { Amount uint64 `json:"amount"` } +// depositInfoAPIV4 is an API V4 deposit structure. +type depositInfoAPIV4 struct { + PublicKey string `json:"validator_pubkey"` + WithdrawalCredentials string `json:"withdrawal_credentials"` + Signature string `json:"validator_signature"` + DepositDataRoot string `json:"deposit_data_root"` + DepositMessageRoot string `json:"deposit_message_root"` + ForkVersion string `json:"fork_version"` + Amount string `json:"amount"` + Version string `json:"data_version"` +} + // DepositInfoFromJSON obtains deposit info from any supported JSON format. func DepositInfoFromJSON(input []byte) ([]*DepositInfo, error) { // Work out the type of data that we're dealing with, and decode it appropriately. @@ -100,10 +112,13 @@ func DepositInfoFromJSON(input []byte) ([]*DepositInfo, error) { if err != nil { depositInfo, err = tryV1DepositInfoFromJSON(input) if err != nil { - depositInfo, err = tryCLIDepositInfoFromJSON(input) + depositInfo, err = tryAPIV4DepositInfoFromJSON(input) if err != nil { - // Give up - return nil, errors.New("unknown deposit data format") + depositInfo, err = tryCLIDepositInfoFromJSON(input) + if err != nil { + // Give up + return nil, errors.New("unknown deposit data format") + } } } } @@ -184,6 +199,62 @@ func tryV3DepositInfoFromJSON(data []byte) ([]*DepositInfo, error) { return depositInfos, nil } +func tryAPIV4DepositInfoFromJSON(data []byte) ([]*DepositInfo, error) { + var depositData []*depositInfoAPIV4 + err := json.Unmarshal(data, &depositData) + if err != nil { + return nil, err + } + + depositInfos := make([]*DepositInfo, len(depositData)) + for i, deposit := range depositData { + if deposit.Version != "4" { + return nil, errors.New("incorrect V4 deposit version") + } + publicKey, err := hex.DecodeString(strings.TrimPrefix(deposit.PublicKey, "0x")) + if err != nil { + return nil, errors.New("public key invalid") + } + withdrawalCredentials, err := hex.DecodeString(strings.TrimPrefix(deposit.WithdrawalCredentials, "0x")) + if err != nil { + return nil, errors.New("withdrawal credentials invalid") + } + signature, err := hex.DecodeString(strings.TrimPrefix(deposit.Signature, "0x")) + if err != nil { + return nil, errors.New("signature invalid") + } + depositDataRoot, err := hex.DecodeString(strings.TrimPrefix(deposit.DepositDataRoot, "0x")) + if err != nil { + return nil, errors.New("deposit data root invalid") + } + depositMessageRoot, err := hex.DecodeString(strings.TrimPrefix(deposit.DepositMessageRoot, "0x")) + if err != nil { + return nil, errors.New("deposit message root invalid") + } + forkVersion, err := hex.DecodeString(strings.TrimPrefix(deposit.ForkVersion, "0x")) + if err != nil { + return nil, errors.New("fork version invalid") + } + amount, err := strconv.ParseUint(deposit.Amount, 10, 64) + if err != nil { + return nil, errors.New("amount invalid") + } + + depositInfos[i] = &DepositInfo{ + PublicKey: publicKey, + WithdrawalCredentials: withdrawalCredentials, + Signature: signature, + DepositDataRoot: depositDataRoot, + DepositMessageRoot: depositMessageRoot, + ForkVersion: forkVersion, + Amount: amount, + Version: 4, + } + } + + return depositInfos, nil +} + func tryV3bDepositInfoFromJSON(data []byte) ([]*DepositInfo, error) { var depositData []*depositInfoV3b err := json.Unmarshal(data, &depositData)