arnaucube
arnaucube/eth-kzg-ceremony-altPublic Self-hosted repository
eth-kzg-ceremony-alt/client/req.go
client/req.goRaw
  1package client
  2
  3import (
  4	"bytes"
  5	"encoding/json"
  6	"fmt"
  7	"io"
  8	"io/ioutil"
  9	"net/http"
 10	"strings"
 11
 12	kzgceremony "github.com/arnaucube/eth-kzg-ceremony-alt"
 13)
 14
 15type Client struct {
 16	url string
 17	c   *http.Client
 18}
 19
 20func (c *Client) postWithAuth(url, contentType string, body io.Reader, bearer string) (resp *http.Response, err error) {
 21	req, err := http.NewRequest("POST", url, body)
 22	if err != nil {
 23		return nil, err
 24	}
 25	req.Header.Set("Content-Type", contentType)
 26	req.Header.Add("Authorization", bearer)
 27	return c.c.Do(req)
 28}
 29
 30func NewClient(sequencerURL string) *Client {
 31	httpClient := &http.Client{}
 32	return &Client{
 33		url: sequencerURL,
 34		c:   httpClient,
 35	}
 36}
 37
 38func (c *Client) GetCurrentStatus() (*MsgStatus, error) {
 39	resp, err := c.c.Get(
 40		c.url + "/info/status")
 41	if err != nil {
 42		return nil, err
 43	}
 44	if resp.StatusCode != http.StatusOK {
 45		return nil, fmt.Errorf("unexpected http code: %d", resp.StatusCode)
 46	}
 47
 48	body, err := ioutil.ReadAll(resp.Body)
 49	if err != nil {
 50		return nil, err
 51	}
 52
 53	var msg MsgStatus
 54	err = json.Unmarshal(body, &msg)
 55	return &msg, err
 56}
 57
 58func (c *Client) GetCurrentState() (*kzgceremony.State, error) {
 59	resp, err := c.c.Get(
 60		c.url + "/info/current_state")
 61	if err != nil {
 62		return nil, err
 63	}
 64	if resp.StatusCode != http.StatusOK {
 65		return nil, fmt.Errorf("unexpected http code: %d", resp.StatusCode)
 66	}
 67
 68	body, err := ioutil.ReadAll(resp.Body)
 69	if err != nil {
 70		return nil, err
 71	}
 72
 73	var state *kzgceremony.State
 74	err = json.Unmarshal(body, &state)
 75	return state, err
 76}
 77
 78func (c *Client) GetRequestLink() (*MsgRequestLink, error) {
 79	resp, err := c.c.Get(
 80		c.url + "/auth/request_link")
 81	if err != nil {
 82		return nil, err
 83	}
 84	if resp.StatusCode != http.StatusOK {
 85		switch resp.StatusCode {
 86		case http.StatusBadRequest:
 87			return nil, fmt.Errorf("Invalid request. Missing parameters.")
 88		case http.StatusUnauthorized:
 89			return nil, fmt.Errorf("Eth address doesn't match message signer, or account nonce is too low")
 90		case http.StatusForbidden:
 91			return nil, fmt.Errorf("Invalid HTTP method")
 92		default:
 93			return nil, fmt.Errorf("unexpected http code: %d", resp.StatusCode)
 94		}
 95	}
 96
 97	body, err := ioutil.ReadAll(resp.Body)
 98	if err != nil {
 99		return nil, err
100	}
101
102	var msg MsgRequestLink
103	err = json.Unmarshal(body, &msg)
104	return &msg, err
105}
106
107func (c *Client) PostAuthCallback() (*MsgRequestLink, error) {
108	resp, err := c.c.Get(
109		c.url + "/auth/request_link")
110	if err != nil {
111		return nil, err
112	}
113	if resp.StatusCode != http.StatusOK {
114		switch resp.StatusCode {
115		case http.StatusBadRequest:
116			return nil, fmt.Errorf("Invalid request. Missing parameters.")
117		case http.StatusUnauthorized:
118			return nil, fmt.Errorf("Eth address doesn't match message signer, or account nonce is too low")
119		case http.StatusForbidden:
120			return nil, fmt.Errorf("Invalid HTTP method")
121		default:
122			return nil, fmt.Errorf("unexpected http code: %d", resp.StatusCode)
123		}
124	}
125
126	body, err := ioutil.ReadAll(resp.Body)
127	if err != nil {
128		return nil, err
129	}
130
131	var msg MsgRequestLink
132	err = json.Unmarshal(body, &msg)
133	return &msg, err
134}
135
136type Status int
137
138const (
139	StatusReauth = Status(iota)
140	StatusError
141	StatusWait
142	StatusProceed
143)
144
145func (c *Client) PostTryContribute(sessionID string) (*kzgceremony.BatchContribution, Status, error) {
146	bearer := "Bearer " + sessionID
147	resp, err := c.postWithAuth(
148		c.url+"/lobby/try_contribute", "application/json", nil, bearer)
149	if err != nil {
150		return nil, StatusError, err
151	}
152
153	body, err := ioutil.ReadAll(resp.Body)
154	if err != nil {
155		return nil, StatusError, err
156	}
157
158	if resp.StatusCode != http.StatusOK {
159		switch resp.StatusCode {
160		case http.StatusBadRequest:
161			return nil, StatusWait, fmt.Errorf("call came to early. rate limited")
162		case http.StatusUnauthorized:
163			return nil, StatusReauth, fmt.Errorf("unkown session id. unauthorized access")
164		default:
165			return nil, StatusWait, fmt.Errorf("unexpected http code: %d", resp.StatusCode)
166		}
167	}
168
169	// note: a 200 (Ok) code by the Sequencer on try_contribute doesn't
170	// mean that the contributor has been selected. It could mean that the
171	// Sequencer is returning the error AnotherContributionInProgress in a
172	// json msg (see
173	// https://github.com/ethereum/kzg-ceremony-sequencer/blob/2538f2f08d4db880d7f4608e964df0b695bc7d2f/src/api/v1/error_response.rs#L105
174	// )
175
176	// check if body contains the error message of "another contribution in
177	// progress" (despite http statuscode being 200 (Ok))
178	if strings.Contains(string(body), "another contribution in progress") {
179		return nil, StatusWait, fmt.Errorf("another contribution in progress")
180	}
181
182	err = ioutil.WriteFile("prevBatchContribution.json", body, 0600)
183	if err != nil {
184		return nil, StatusError, err
185	}
186	bc := &kzgceremony.BatchContribution{}
187	err = json.Unmarshal(body, bc)
188	return bc, StatusProceed, err
189}
190
191func (c *Client) PostAbortContribution(sessionID string) ([]byte, error) {
192	bearer := "Bearer " + sessionID
193	resp, err := c.postWithAuth(
194		c.url+"/contribution/abort", "application/json", nil, bearer)
195	if err != nil {
196		return nil, err
197	}
198	body, err := ioutil.ReadAll(resp.Body)
199	if err != nil {
200		return nil, err
201	}
202	fmt.Println("body", string(body))
203
204	if resp.StatusCode != http.StatusOK {
205		switch resp.StatusCode {
206		case http.StatusBadRequest:
207			return nil, fmt.Errorf("invalid request")
208		case http.StatusUnauthorized:
209			return nil, fmt.Errorf("unkown session id. unauthorized access")
210		default:
211			return nil, fmt.Errorf("unexpected http code: %d", resp.StatusCode)
212		}
213	}
214
215	return body, nil
216}
217
218func (c *Client) PostContribute(sessionID string, bc *kzgceremony.BatchContribution) (*MsgContributeReceipt, error) {
219	bearer := "Bearer " + sessionID
220
221	jsonBC, err := json.Marshal(bc)
222	if err != nil {
223		return nil, err
224	}
225
226	resp, err := c.postWithAuth(
227		c.url+"/contribute", "application/json", bytes.NewBuffer(jsonBC), bearer)
228	if err != nil {
229		return nil, err
230	}
231	if resp.StatusCode != http.StatusOK {
232		switch resp.StatusCode {
233		case http.StatusBadRequest:
234			return nil, fmt.Errorf("invalid request")
235		default:
236			return nil, fmt.Errorf("unexpected http code: %d", resp.StatusCode)
237		}
238	}
239
240	body, err := ioutil.ReadAll(resp.Body)
241	if err != nil {
242		return nil, err
243	}
244
245	var msg MsgContributeReceipt
246	err = json.Unmarshal(body, &msg)
247	return &msg, err
248}