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}