1
1
package cmd
2
2
3
3
import (
4
+ "bytes"
5
+ "delta/api"
4
6
c "delta/config"
7
+ "delta/utils"
8
+ "encoding/json"
9
+ "fmt"
5
10
"github.com/urfave/cli/v2"
11
+ "io"
12
+ "mime/multipart"
13
+ "net/http"
14
+ "os"
6
15
)
7
16
8
- // TODO: add a command to make deals via CLI
17
+ type DealMetadata api.DealRequest
18
+ type DealResponse api.DealResponse
19
+
9
20
func DealCmd (cfg * c.DeltaConfig ) []* cli.Command {
10
21
// add a command to run API node
11
22
var dealCommands []* cli.Command
12
23
13
24
dealCmd := & cli.Command {
14
- Name : "deal" ,
15
- Usage : "Make a delta storage deal" ,
25
+ Name : "deal" ,
26
+ Usage : "Make a delta storage deal" ,
27
+ Description : "Make a delta storage deal. The type of deal can be either e2e (online) or import (offline)." ,
16
28
Flags : []cli.Flag {
17
29
& cli.StringFlag {
18
- Name : "content" ,
19
- Usage : "content to store" ,
30
+ Name : "delta-host" ,
31
+ Usage : "the delta host" ,
32
+ Value : "http://localhost:1414" ,
33
+ },
34
+ & cli.StringFlag {
35
+ Name : "type" ,
36
+ Usage : "e2e (online) or import (offline)" ,
37
+ },
38
+ & cli.StringFlag {
39
+ Name : "file" ,
40
+ Usage : "file to make a deal with. Required only for e2e deals." ,
20
41
},
21
42
& cli.StringFlag {
22
43
Name : "metadata" ,
@@ -27,6 +48,219 @@ func DealCmd(cfg *c.DeltaConfig) []*cli.Command {
27
48
Usage : "The API key to use for the request" ,
28
49
},
29
50
},
51
+ Action : func (context * cli.Context ) error {
52
+ deltaHostParam := context .String ("delta-host" )
53
+ fileParam := context .String ("file" )
54
+ typeParam := context .String ("type" )
55
+ apiKeyParam := context .String ("api-key" )
56
+ metadataParam := context .String ("metadata" )
57
+ var metadata DealMetadata
58
+ var metadataArr []DealMetadata
59
+ var e2eResponse DealResponse
60
+ var importResponse []DealResponse
61
+
62
+ // validate
63
+ if typeParam == "e2e" {
64
+ if fileParam == "" {
65
+ fmt .Println ("file is required for e2e deals" )
66
+ os .Exit (1 )
67
+ }
68
+ }
69
+ if apiKeyParam == "" {
70
+ fmt .Println ("api-key is required" )
71
+ os .Exit (1 )
72
+ }
73
+ if metadataParam == "" {
74
+ fmt .Println ("metadata is required" )
75
+ os .Exit (1 )
76
+ }
77
+
78
+ if typeParam == "import" {
79
+ if fileParam != "" {
80
+ fmt .Println ("file is not required for import deals" )
81
+ os .Exit (1 )
82
+ }
83
+ }
84
+
85
+ var endpoint string
86
+ url := deltaHostParam + "/api/v1"
87
+ if typeParam == "e2e" {
88
+
89
+ err := json .Unmarshal ([]byte (metadataParam ), & metadata )
90
+ if err != nil {
91
+ var buffer bytes.Buffer
92
+ err = utils .PrettyEncode (DealResponse {
93
+ Status : "error" ,
94
+ Message : "Error unmarshalling metadata" ,
95
+ }, & buffer )
96
+ if err != nil {
97
+ fmt .Println (err )
98
+ }
99
+ fmt .Println (buffer .String ())
100
+ }
101
+
102
+ endpoint = url + "/deal/content"
103
+
104
+ // Create a new HTTP request with the desired method and URL.
105
+ req , err := http .NewRequest ("POST" , endpoint , nil )
106
+ if err != nil {
107
+ panic (err )
108
+ }
109
+
110
+ // Set the Authorization header.
111
+ req .Header .Set ("Authorization" , "Bearer " + apiKeyParam )
112
+
113
+ // Create a new multipart writer for the request body.
114
+ body := & bytes.Buffer {}
115
+ writer := multipart .NewWriter (body )
116
+
117
+ // Add the data file to the multipart writer.
118
+ file , err := os .Open (fileParam )
119
+ if err != nil {
120
+ panic (err )
121
+ }
122
+
123
+ part , err := writer .CreateFormFile ("data" , file .Name ())
124
+ if err != nil {
125
+ panic (err )
126
+ }
127
+ _ , err = io .Copy (part , file )
128
+ if err != nil {
129
+ panic (err )
130
+ }
131
+
132
+ err = writer .WriteField ("metadata" , metadataParam )
133
+ if err != nil {
134
+ panic (err )
135
+ }
136
+
137
+ // Close the multipart writer.
138
+ err = writer .Close ()
139
+ if err != nil {
140
+ panic (err )
141
+ }
142
+
143
+ // Set the content type header for the request.
144
+ req .Header .Set ("Content-Type" , writer .FormDataContentType ())
145
+
146
+ // Set the request body to the multipart writer's buffer.
147
+ req .Body = io .NopCloser (body )
148
+
149
+ // Send the HTTP request and print the response.
150
+ resp , err := http .DefaultClient .Do (req )
151
+ if err != nil {
152
+ panic (err )
153
+ }
154
+ defer resp .Body .Close ()
155
+
156
+ fmt .Println (resp .Status )
157
+ if resp .StatusCode != 200 {
158
+
159
+ errorResponse := struct {
160
+ Error struct {
161
+ Code int `json:"code"`
162
+ Reason string `json:"reason"`
163
+ Details string `json:"details"`
164
+ }
165
+ }{}
166
+
167
+ err = json .NewDecoder (resp .Body ).Decode (& errorResponse )
168
+ if err != nil {
169
+ fmt .Println (err )
170
+ }
171
+
172
+ var buffer bytes.Buffer
173
+ err = utils .PrettyEncode (errorResponse , & buffer )
174
+ if err != nil {
175
+ fmt .Println (err )
176
+ }
177
+ fmt .Println (buffer .String ())
178
+ return nil
179
+ }
180
+ err = json .NewDecoder (resp .Body ).Decode (& e2eResponse )
181
+ if err != nil {
182
+ panic (err )
183
+ }
184
+ var buffer bytes.Buffer
185
+ err = utils .PrettyEncode (e2eResponse , & buffer )
186
+ if err != nil {
187
+ fmt .Println (err )
188
+ }
189
+ fmt .Println (buffer .String ())
190
+ return nil
191
+ }
192
+ if typeParam == "import" {
193
+
194
+ err := json .Unmarshal ([]byte (metadataParam ), & metadataArr )
195
+ if err != nil {
196
+ var buffer bytes.Buffer
197
+ err = utils .PrettyEncode (DealResponse {
198
+ Status : "error" ,
199
+ Message : "Error unmarshalling metadata" ,
200
+ }, & buffer )
201
+ if err != nil {
202
+ fmt .Println (err )
203
+ }
204
+ fmt .Println (buffer .String ())
205
+ }
206
+ endpoint = url + "/deal/piece-commitments"
207
+
208
+ // Create a new HTTP request with the desired method and URL.
209
+ req , err := http .NewRequest ("POST" , endpoint , bytes .NewBuffer ([]byte (metadataParam )))
210
+ if err != nil {
211
+ panic (err )
212
+ }
213
+
214
+ // Set the Authorization and Content-Type headers.
215
+ req .Header .Set ("Authorization" , "Bearer " + apiKeyParam )
216
+ req .Header .Set ("Content-Type" , "application/json" )
217
+
218
+ // Send the HTTP request and print the response.
219
+ resp , err := http .DefaultClient .Do (req )
220
+ if err != nil {
221
+ panic (err )
222
+ }
223
+ defer resp .Body .Close ()
224
+
225
+ if resp .StatusCode != 200 {
226
+ errorResponse := struct {
227
+ Error struct {
228
+ Code int `json:"code"`
229
+ Reason string `json:"reason"`
230
+ Details string `json:"details"`
231
+ }
232
+ }{}
233
+
234
+ err = json .NewDecoder (resp .Body ).Decode (& errorResponse )
235
+ if err != nil {
236
+ fmt .Println (err )
237
+ }
238
+
239
+ var buffer bytes.Buffer
240
+ err = utils .PrettyEncode (errorResponse , & buffer )
241
+ if err != nil {
242
+ fmt .Println (err )
243
+ }
244
+ fmt .Println (buffer .String ())
245
+ return nil
246
+ }
247
+ err = json .NewDecoder (resp .Body ).Decode (& importResponse )
248
+ if err != nil {
249
+ panic (err )
250
+ }
251
+
252
+ // print output
253
+
254
+ var buffer bytes.Buffer
255
+ err = utils .PrettyEncode (importResponse , & buffer )
256
+ if err != nil {
257
+ fmt .Println (err )
258
+ }
259
+ fmt .Println (buffer .String ())
260
+ return nil
261
+ }
262
+ return nil
263
+ },
30
264
}
31
265
dealCommands = append (dealCommands , dealCmd )
32
266
0 commit comments