1
1
use std:: {
2
2
fs:: File ,
3
- io:: { Result , Write } ,
3
+ io:: { Error , ErrorKind , Result , Write } ,
4
4
path:: Path ,
5
5
} ;
6
6
@@ -9,12 +9,19 @@ use crate::{
9
9
DecodeTxArgs , DecodeTxResponse , IssueTxArgs , IssueTxResponse , PingResponse , ResolveArgs ,
10
10
ResolveResponse ,
11
11
} ,
12
- chain:: tx:: { tx:: TransactionType , unsigned:: TransactionData } ,
12
+ chain:: tx:: {
13
+ decoder:: { self , TypedData } ,
14
+ tx:: TransactionType ,
15
+ unsigned:: TransactionData ,
16
+ } ,
17
+ } ;
18
+ use avalanche_types:: key:: {
19
+ self ,
20
+ secp256k1:: { private_key:: Key , signature:: Sig } ,
13
21
} ;
14
- use avalanche_types:: key;
15
22
use http:: { Method , Request } ;
16
23
use hyper:: { body, client:: HttpConnector , Body , Client as HyperClient } ;
17
- use jsonrpc_core:: { Call , Id , MethodCall , Params , Version } ;
24
+ use jsonrpc_core:: { Call , Id , MethodCall , Params , Value , Version } ;
18
25
use serde:: de;
19
26
20
27
pub use http:: Uri ;
@@ -23,13 +30,19 @@ pub use http::Uri;
23
30
pub struct Client < C > {
24
31
id : u64 ,
25
32
client : HyperClient < C > ,
26
- pub uri : Uri ,
33
+ endpoint : Uri ,
34
+ private_key : Option < Key > ,
27
35
}
28
36
29
37
impl Client < HttpConnector > {
30
- pub fn new ( uri : Uri ) -> Self {
38
+ pub fn new ( endpoint : Uri ) -> Self {
31
39
let client = HyperClient :: new ( ) ;
32
- Self { id : 0 , client, uri }
40
+ Self {
41
+ id : 0 ,
42
+ client,
43
+ endpoint,
44
+ private_key : None ,
45
+ }
33
46
}
34
47
}
35
48
@@ -40,6 +53,16 @@ impl Client<HttpConnector> {
40
53
Id :: Num ( id)
41
54
}
42
55
56
+ pub fn set_endpoint ( mut self , endpoint : Uri ) -> Self {
57
+ self . endpoint = endpoint;
58
+ self
59
+ }
60
+
61
+ pub fn set_private_key ( mut self , private_key : Key ) -> Self {
62
+ self . private_key = Some ( private_key) ;
63
+ self
64
+ }
65
+
43
66
/// Returns a serialized json request as string and the request id.
44
67
pub fn raw_request ( & mut self , method : & str , params : & Params ) -> ( Id , String ) {
45
68
let id = self . next_id ( ) ;
@@ -55,6 +78,14 @@ impl Client<HttpConnector> {
55
78
)
56
79
}
57
80
81
+ /// Returns a recoverable signature from bytes.
82
+ pub fn sign_digest ( & self , dh : & [ u8 ] ) -> Result < Sig > {
83
+ if let Some ( pk) = & self . private_key {
84
+ pk. sign_digest ( dh) ?;
85
+ }
86
+ Err ( Error :: new ( ErrorKind :: Other , "private key not set" ) )
87
+ }
88
+
58
89
/// Returns a PingResponse from client request.
59
90
pub async fn ping ( & mut self ) -> Result < PingResponse > {
60
91
let ( _id, json_request) = self . raw_request ( "ping" , & Params :: None ) ;
@@ -64,40 +95,48 @@ impl Client<HttpConnector> {
64
95
}
65
96
66
97
/// Returns a DecodeTxResponse from client request.
67
- pub async fn decode_tx ( & mut self , args : DecodeTxArgs ) -> Result < DecodeTxResponse > {
68
- let arg_bytes = serde_json:: to_vec ( & args) ?;
69
- let params: Params = serde_json:: from_slice ( & arg_bytes) ?;
70
- let ( _id, json_request) = self . raw_request ( "decodeTx" , & params) ;
98
+ pub async fn decode_tx ( & mut self , tx_data : TransactionData ) -> Result < DecodeTxResponse > {
99
+ let arg_value = serde_json:: to_value ( & DecodeTxArgs { tx_data } ) ?;
100
+ let ( _id, json_request) = self . raw_request ( "decodeTx" , & Params :: Array ( vec ! [ arg_value] ) ) ;
71
101
let resp = self . post_de :: < DecodeTxResponse > ( & json_request) . await ?;
72
102
73
103
Ok ( resp)
74
104
}
75
105
76
106
/// Returns a IssueTxResponse from client request.
77
- pub async fn issue_tx ( & mut self , args : IssueTxArgs ) -> Result < IssueTxResponse > {
78
- let arg_bytes = serde_json:: to_vec ( & args) ?;
79
- let params: Params = serde_json:: from_slice ( & arg_bytes) ?;
80
- let ( _id, json_request) = self . raw_request ( "issueTx" , & params) ;
107
+ pub async fn issue_tx ( & mut self , typed_data : & TypedData ) -> Result < IssueTxResponse > {
108
+ let dh = decoder:: hash_structured_data ( typed_data) ?;
109
+ let sig = self . sign_digest ( & dh. as_bytes ( ) ) ?. to_bytes ( ) . to_vec ( ) ;
110
+ log:: debug!( "signature: {:?}" , sig) ;
111
+
112
+ let arg_value = serde_json:: to_value ( & IssueTxArgs {
113
+ typed_data : typed_data. to_owned ( ) ,
114
+ signature : sig,
115
+ } ) ?;
116
+ let ( _id, json_request) = self . raw_request ( "issueTx" , & Params :: Array ( vec ! [ arg_value] ) ) ;
81
117
let resp = self . post_de :: < IssueTxResponse > ( & json_request) . await ?;
82
118
83
119
Ok ( resp)
84
120
}
85
121
86
122
/// Returns a ResolveResponse from client request.
87
- pub async fn resolve ( & mut self , args : ResolveArgs ) -> Result < ResolveResponse > {
88
- let arg_bytes = serde_json:: to_vec ( & args) ?;
89
- let params: Params = serde_json:: from_slice ( & arg_bytes) ?;
90
- let ( _id, json_request) = self . raw_request ( "resolve" , & params) ;
123
+ pub async fn resolve ( & mut self , space : & str , key : & str ) -> Result < ResolveResponse > {
124
+ let arg_value = serde_json:: to_value ( & ResolveArgs {
125
+ space : space. as_bytes ( ) . to_vec ( ) ,
126
+ key : key. as_bytes ( ) . to_vec ( ) ,
127
+ } ) ?;
128
+ let ( _id, json_request) = self . raw_request ( "issueTx" , & Params :: Array ( vec ! [ arg_value] ) ) ;
91
129
let resp = self . post_de :: < ResolveResponse > ( & json_request) . await ?;
92
130
93
131
Ok ( resp)
94
132
}
95
133
96
134
/// Returns a deserialized response from client request.
97
135
pub async fn post_de < T : de:: DeserializeOwned > ( & self , json : & str ) -> Result < T > {
136
+ println ! ( "json: {}" , json) ;
98
137
let req = Request :: builder ( )
99
138
. method ( Method :: POST )
100
- . uri ( self . uri . to_string ( ) )
139
+ . uri ( self . endpoint . to_string ( ) )
101
140
. header ( "content-type" , "application/json-rpc" )
102
141
. body ( Body :: from ( json. to_owned ( ) ) )
103
142
. map_err ( |e| {
@@ -107,20 +146,30 @@ impl Client<HttpConnector> {
107
146
)
108
147
} ) ?;
109
148
110
- let resp = self . client . request ( req) . await . map_err ( |e| {
149
+ let mut resp = self . client . request ( req) . await . map_err ( |e| {
111
150
std:: io:: Error :: new (
112
151
std:: io:: ErrorKind :: Other ,
113
152
format ! ( "client post request failed: {}" , e) ,
114
153
)
115
154
} ) ?;
116
155
117
- let bytes = body:: to_bytes ( resp. into_body ( ) )
156
+ let bytes = body:: to_bytes ( resp. body_mut ( ) )
118
157
. await
119
158
. map_err ( |e| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , e. to_string ( ) ) ) ?;
120
- let resp = serde_json:: from_slice ( & bytes) . map_err ( |e| {
159
+
160
+ // deserialize bytes to value
161
+ let v: Value = serde_json:: from_slice ( & bytes) . map_err ( |e| {
162
+ std:: io:: Error :: new (
163
+ std:: io:: ErrorKind :: Other ,
164
+ format ! ( "failed to deserialize response to value: {}" , e) ,
165
+ )
166
+ } ) ?;
167
+
168
+ // deserialize result to T
169
+ let resp = serde_json:: from_value ( v[ "result" ] . to_owned ( ) ) . map_err ( |e| {
121
170
std:: io:: Error :: new (
122
171
std:: io:: ErrorKind :: Other ,
123
- format ! ( "failed to create client request : {}" , e) ,
172
+ format ! ( "failed to deserialize response : {}" , e) ,
124
173
)
125
174
} ) ?;
126
175
0 commit comments