near_jsonrpc_client/methods/
mod.rs1use std::io;
3
4use serde::{Deserialize, Serialize};
5use serde_json::json;
6use thiserror::Error;
7
8mod private {
9 pub trait Sealed {}
10}
11
12pub trait RpcMethod: private::Sealed
14where
15 Self::Response: RpcHandlerResponse,
16 Self::Error: RpcHandlerError,
17{
18 type Response;
19 type Error;
20
21 fn method_name(&self) -> &str;
22
23 fn params(&self) -> Result<serde_json::Value, io::Error>;
24
25 fn parse_handler_response(
26 response: serde_json::Value,
27 ) -> Result<Result<Self::Response, Self::Error>, serde_json::Error> {
28 Self::Response::parse(response).map(Ok)
29 }
30}
31
32impl<T> private::Sealed for &T where T: private::Sealed {}
33impl<T> RpcMethod for &T
34where
35 T: RpcMethod,
36{
37 type Response = T::Response;
38 type Error = T::Error;
39
40 fn method_name(&self) -> &str {
41 T::method_name(self)
42 }
43
44 fn params(&self) -> Result<serde_json::Value, io::Error> {
45 T::params(self)
46 }
47
48 fn parse_handler_response(
49 response: serde_json::Value,
50 ) -> Result<Result<Self::Response, Self::Error>, serde_json::Error> {
51 T::parse_handler_response(response)
52 }
53}
54
55pub trait RpcHandlerResponse: serde::de::DeserializeOwned {
57 fn parse(value: serde_json::Value) -> Result<Self, serde_json::Error> {
58 serde_json::from_value(value)
59 }
60}
61
62pub trait RpcHandlerError: serde::de::DeserializeOwned {
64 fn parse(handler_error: serde_json::Value) -> Result<Self, serde_json::Error> {
66 serde_json::from_value(handler_error)
67 }
68
69 fn parse_legacy_error(_error: serde_json::Value) -> Option<Result<Self, serde_json::Error>> {
75 None
76 }
77}
78
79pub mod block;
80pub mod broadcast_tx_async;
81pub mod broadcast_tx_commit;
82pub mod chunk;
83pub mod gas_price;
84pub mod health;
85pub mod light_client_proof;
86pub mod network_info;
87pub mod next_light_client_block;
88pub mod query;
89pub mod send_tx;
90pub mod status;
91pub mod tx;
92pub mod validators;
93
94mod experimental;
96pub use experimental::EXPERIMENTAL_changes;
97pub use experimental::EXPERIMENTAL_changes_in_block;
98pub use experimental::EXPERIMENTAL_genesis_config;
99pub use experimental::EXPERIMENTAL_protocol_config;
100pub use experimental::EXPERIMENTAL_receipt;
101pub use experimental::EXPERIMENTAL_tx_status;
102pub use experimental::EXPERIMENTAL_validators_ordered;
103#[cfg(feature = "any")]
107mod any;
108#[cfg(feature = "any")]
109pub use any::{request as any, RpcAnyRequest};
110#[cfg(feature = "sandbox")]
114mod sandbox;
115
116#[cfg(feature = "sandbox")]
117pub use sandbox::sandbox_patch_state;
118
119#[cfg(feature = "sandbox")]
120pub use sandbox::sandbox_fast_forward;
121#[cfg(feature = "adversarial")]
125mod adversarial;
126
127#[cfg(feature = "adversarial")]
128pub use adversarial::adv_set_weight;
129
130#[cfg(feature = "adversarial")]
131pub use adversarial::adv_disable_header_sync;
132
133#[cfg(feature = "adversarial")]
134pub use adversarial::adv_disable_doomslug;
135
136#[cfg(feature = "adversarial")]
137pub use adversarial::adv_produce_blocks;
138
139#[cfg(feature = "adversarial")]
140pub use adversarial::adv_switch_to_height;
141
142#[cfg(feature = "adversarial")]
143pub use adversarial::adv_get_saved_blocks;
144
145#[cfg(feature = "adversarial")]
146pub use adversarial::adv_check_store;
147pub fn to_json<M: RpcMethod>(method: &M) -> Result<serde_json::Value, io::Error> {
151 let request_payload = near_jsonrpc_primitives::message::Message::request(
152 method.method_name().to_string(),
153 method.params()?,
154 );
155
156 Ok(json!(request_payload))
157}
158
159mod common {
160 use super::*;
161
162 macro_rules! _parse_unknown_block {
166 ($json:expr => $err_ty:ident) => {
167 match $json {
168 err => {
169 if err["name"] == "UNKNOWN_BLOCK" {
170 Ok($err_ty::UnknownBlock {
171 error_message: "".to_string(),
172 })
173 } else {
174 serde_json::from_value(err)
175 }
176 }
177 }
178 };
179 }
180 pub(crate) use _parse_unknown_block as parse_unknown_block;
181
182 pub fn serialize_signed_transaction(
183 tx: &near_primitives::transaction::SignedTransaction,
184 ) -> Result<String, io::Error> {
185 Ok(near_primitives::serialize::to_base64(&borsh::to_vec(&tx)?))
186 }
187
188 #[cfg(feature = "adversarial")]
190 impl RpcHandlerError for () {}
191
192 #[cfg(feature = "adversarial")]
194 impl RpcHandlerResponse for () {
195 fn parse(_value: serde_json::Value) -> Result<Self, serde_json::Error> {
196 Ok(())
197 }
198 }
199
200 #[cfg(feature = "any")]
201 impl RpcHandlerResponse for serde_json::Value {
202 fn parse(value: serde_json::Value) -> Result<Self, serde_json::Error> {
203 Ok(value)
204 }
205 }
206
207 #[cfg(feature = "any")]
208 impl RpcHandlerError for serde_json::Value {
209 fn parse(handler_error: serde_json::Value) -> Result<Self, serde_json::Error> {
210 Ok(handler_error)
211 }
212 }
213
214 impl RpcHandlerResponse for near_primitives::views::FinalExecutionOutcomeView {}
216
217 impl RpcHandlerError for near_jsonrpc_primitives::types::transactions::RpcTransactionError {
219 fn parse_legacy_error(value: serde_json::Value) -> Option<Result<Self, serde_json::Error>> {
220 match serde_json::from_value::<near_jsonrpc_primitives::errors::ServerError>(value) {
221 Ok(near_jsonrpc_primitives::errors::ServerError::TxExecutionError(
222 near_primitives::errors::TxExecutionError::InvalidTxError(context),
223 )) => Some(Ok(Self::InvalidTransaction { context })),
224 Err(err) => Some(Err(err)),
225 _ => None,
226 }
227 }
228 }
229
230 impl RpcHandlerError for near_jsonrpc_primitives::types::status::RpcStatusError {}
232
233 impl RpcHandlerError for near_jsonrpc_primitives::types::changes::RpcStateChangesError {
235 fn parse(value: serde_json::Value) -> Result<Self, serde_json::Error> {
236 parse_unknown_block!(value => Self)
237 }
238 }
239
240 impl RpcHandlerResponse for near_jsonrpc_primitives::types::transactions::RpcTransactionResponse {}
242
243 impl RpcHandlerError for near_jsonrpc_primitives::types::validator::RpcValidatorError {}
245}