@@ -134,6 +134,96 @@ impl Client {
134134 Err ( std:: io:: Error :: other ( format ! ( "invalid response: {res:?}" ) ) )
135135 }
136136
137+ /// Make a "register-dna" call.
138+ pub async fn register_dna (
139+ & self ,
140+ config : & RuntimeConfigFile ,
141+ dna_hash : String ,
142+ agreement_id : String ,
143+ price_sheet_hash : Option < String > ,
144+ metadata : Option < serde_json:: Value > ,
145+ ) -> Result < serde_json:: Value > {
146+ let mut url = self . url . clone ( ) ;
147+ url. set_path ( "/register-dna" ) ;
148+
149+ #[ derive( serde:: Serialize ) ]
150+ #[ serde( rename_all = "camelCase" ) ]
151+ struct Req {
152+ drone_pub_key : String ,
153+ dna_hash : String ,
154+ agreement_id : String ,
155+ price_sheet_hash : Option < String > ,
156+ drone_signature : String ,
157+ signature_timestamp : u64 ,
158+ metadata : Option < serde_json:: Value > ,
159+ }
160+
161+ let drone_pub_key = config. drone_pub_key . clone ( ) ;
162+ let signature_timestamp = std:: time:: SystemTime :: UNIX_EPOCH
163+ . elapsed ( )
164+ . expect ( "can get time" )
165+ . as_millis ( ) as u64 ;
166+
167+ #[ derive( serde:: Serialize ) ]
168+ #[ serde( rename_all = "camelCase" ) ]
169+ struct Sig {
170+ drone_pub_key : String ,
171+ dna_hash : String ,
172+ agreement_id : String ,
173+ timestamp : u64 ,
174+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
175+ price_sheet_hash : Option < String > ,
176+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
177+ metadata : Option < serde_json:: Value > ,
178+ }
179+
180+ let sig = serde_json:: to_string ( & Sig {
181+ drone_pub_key : drone_pub_key. clone ( ) ,
182+ dna_hash : dna_hash. clone ( ) ,
183+ agreement_id : agreement_id. clone ( ) ,
184+ timestamp : signature_timestamp,
185+ price_sheet_hash : price_sheet_hash. clone ( ) ,
186+ metadata : metadata. clone ( ) ,
187+ } ) ?;
188+
189+ let drone_signature = config. rt_drone_sec_key . sign ( sig. as_bytes ( ) ) ?;
190+
191+ let res = self
192+ . client
193+ . post ( url)
194+ . json ( & Req {
195+ drone_pub_key,
196+ dna_hash,
197+ agreement_id,
198+ price_sheet_hash,
199+ drone_signature,
200+ signature_timestamp,
201+ metadata,
202+ } )
203+ . send ( )
204+ . await
205+ . map_err ( std:: io:: Error :: other) ?;
206+
207+ if res. error_for_status_ref ( ) . is_err ( ) {
208+ return Err ( std:: io:: Error :: other (
209+ res. text ( ) . await . map_err ( std:: io:: Error :: other) ?,
210+ ) ) ;
211+ }
212+
213+ let res: serde_json:: Value =
214+ res. json ( ) . await . map_err ( std:: io:: Error :: other) ?;
215+
216+ if let Some ( obj) = res. as_object ( )
217+ && let Some ( p) = obj. get ( "success" )
218+ && let Some ( b) = p. as_bool ( )
219+ && b
220+ {
221+ return Ok ( res) ;
222+ }
223+
224+ Err ( std:: io:: Error :: other ( format ! ( "invalid response: {res:?}" ) ) )
225+ }
226+
137227 /// Submit metrics to the endpoint.
138228 pub async fn metrics (
139229 & self ,
0 commit comments