nash_protocol/protocol/sign_states/
request.rs1use super::super::{general_canonical_string, RequestPayloadSignature};
2use super::blockchain::sign_state_data;
3use super::types::{ClientSignedState, SignStatesRequest};
4use crate::errors::{ProtocolError, Result};
5use crate::graphql;
6use crate::graphql::sign_states;
7use crate::types::Blockchain;
8use crate::utils::{bigint_to_nash_r, bigint_to_nash_sig, current_time_as_i64};
9use graphql_client::GraphQLQuery;
10
11use super::super::signer::Signer;
12
13impl SignStatesRequest {
14 pub fn make_query(
16 &self,
17 signer: &Signer,
18 ) -> Result<graphql_client::QueryBody<sign_states::Variables>> {
19 let (signed_orders, signed_states) = match &self.input_states {
21 None => (vec![], vec![]),
22 Some(states) => {
23 let mut signed_orders = Vec::new();
24 for order in &states.recycled_orders {
25 if let false = order.verify() {
26 return Err(ProtocolError(
27 "Recycled order payload failed to verify. Refusing to sign",
28 ));
29 }
30 let signed = sign_state_data(order.state(), signer)?;
31 signed_orders.push(signed);
32 }
33
34 let mut signed_states = Vec::new();
35 for state in &states.states {
36 if let false = state.verify() {
37 return Err(ProtocolError(
38 "State balance payload failed to verify. Refusing to sign",
39 ));
40 }
41 let signed = sign_state_data(state.state(), signer)?;
42 signed_states.push(signed);
43 }
44
45 (signed_orders, signed_states)
46 }
47 };
48 let mut params = sign_states::Variables {
49 payload: sign_states::SignStatesParams {
50 timestamp: current_time_as_i64(),
51 sync_all: Some(true),
52 signed_recycled_orders: Some(
53 signed_orders.iter().map(|x| Some(x.into())).collect(),
54 ),
55 client_signed_states: Some(signed_states.iter().map(|x| Some(x.into())).collect()),
56 },
57 signature: RequestPayloadSignature::empty().into(),
58 };
59 let sig_payload = sign_states_canonical_string(¶ms);
60 let sig = signer.sign_canonical_string(&sig_payload);
61 params.signature = sig.into();
62 Ok(graphql::SignStates::build_query(params))
63 }
64}
65
66impl From<RequestPayloadSignature> for sign_states::Signature {
68 fn from(sig: RequestPayloadSignature) -> Self {
69 sign_states::Signature {
70 signed_digest: sig.signed_digest,
71 public_key: sig.public_key,
72 }
73 }
74}
75
76impl From<&ClientSignedState> for sign_states::ClientSignedMessage {
78 fn from(signed_state: &ClientSignedState) -> Self {
79 Self {
80 message: Some(signed_state.message.clone()),
81 blockchain: Some(signed_state.blockchain.into()),
82 r: Some(bigint_to_nash_r(signed_state.r.clone())),
83 signature: Some(bigint_to_nash_sig(signed_state.signature.clone())),
84 }
85 }
86}
87
88pub fn sign_states_canonical_string(variables: &sign_states::Variables) -> String {
90 let serialized_all = serde_json::to_string(variables).unwrap();
91 general_canonical_string(
92 "sign_states".to_string(),
93 serde_json::from_str(&serialized_all).unwrap(),
94 vec![
95 "client_signed_states".to_string(),
96 "signed_recycled_orders".to_string(),
97 "sync_all".to_string(),
98 ],
99 )
100}
101
102impl From<Blockchain> for sign_states::Blockchain {
103 fn from(chain: Blockchain) -> Self {
104 match chain {
105 Blockchain::Ethereum => Self::ETH,
106 Blockchain::NEO => Self::NEO,
107 Blockchain::Bitcoin => Self::BTC,
108 }
109 }
110}