@@ -117,6 +117,10 @@ func (bc *BeaconClient) getJSON(ctx context.Context, requrl string, returnValue
117117}
118118
119119func (bc * BeaconClient ) postJSON (ctx context.Context , requrl string , postData , returnValue interface {}) error {
120+ return bc .postJSONWithHeaders (ctx , requrl , postData , returnValue , nil )
121+ }
122+
123+ func (bc * BeaconClient ) postJSONWithHeaders (ctx context.Context , requrl string , postData , returnValue interface {}, extraHeaders map [string ]string ) error {
120124 logurl := getRedactedURL (requrl )
121125
122126 postDataBytes , err := json .Marshal (postData )
@@ -125,8 +129,8 @@ func (bc *BeaconClient) postJSON(ctx context.Context, requrl string, postData, r
125129 }
126130
127131 reader := bytes .NewReader (postDataBytes )
128- req , err := nethttp .NewRequestWithContext (ctx , "POST" , requrl , reader )
129132
133+ req , err := nethttp .NewRequestWithContext (ctx , "POST" , requrl , reader )
130134 if err != nil {
131135 return err
132136 }
@@ -137,6 +141,10 @@ func (bc *BeaconClient) postJSON(ctx context.Context, requrl string, postData, r
137141 req .Header .Set (headerKey , headerVal )
138142 }
139143
144+ for headerKey , headerVal := range extraHeaders {
145+ req .Header .Set (headerKey , headerVal )
146+ }
147+
140148 client := & nethttp.Client {Timeout : time .Second * 300 }
141149
142150 resp , err := client .Do (req )
@@ -497,6 +505,42 @@ func (bc *BeaconClient) SubmitProposerSlashing(ctx context.Context, slashing *ph
497505 return nil
498506}
499507
508+ type apiAttestationData struct {
509+ Data * phase0.AttestationData `json:"data"`
510+ }
511+
512+ func (bc * BeaconClient ) GetAttestationData (ctx context.Context , slot , committeeIndex uint64 ) (* phase0.AttestationData , error ) {
513+ var attestationData apiAttestationData
514+
515+ err := bc .getJSON (ctx , fmt .Sprintf ("%s/eth/v1/validator/attestation_data?slot=%d&committee_index=%d" , bc .endpoint , slot , committeeIndex ), & attestationData )
516+ if err != nil {
517+ return nil , fmt .Errorf ("error retrieving attestation data: %v" , err )
518+ }
519+
520+ return attestationData .Data , nil
521+ }
522+
523+ // SingleAttestation represents the Electra single attestation format for the v2 API.
524+ type SingleAttestation struct {
525+ CommitteeIndex uint64 `json:"committee_index,string"`
526+ AttesterIndex uint64 `json:"attester_index,string"`
527+ Data * phase0.AttestationData `json:"data"`
528+ Signature string `json:"signature"`
529+ }
530+
531+ func (bc * BeaconClient ) SubmitAttestations (ctx context.Context , attestations []* SingleAttestation ) error {
532+ headers := map [string ]string {
533+ "Eth-Consensus-Version" : "electra" ,
534+ }
535+
536+ err := bc .postJSONWithHeaders (ctx , fmt .Sprintf ("%s/eth/v2/beacon/pool/attestations" , bc .endpoint ), attestations , nil , headers )
537+ if err != nil {
538+ return err
539+ }
540+
541+ return nil
542+ }
543+
500544type NodeIdentity struct {
501545 PeerID string `json:"peer_id"`
502546 ENR string `json:"enr"`
0 commit comments