1use near_api_types::{AccountId, CryptoHash, TxExecutionStatus};
2use near_openapi_client::Client;
3use near_openapi_client::types::{
4 ErrorWrapperForRpcLightClientProofError, ErrorWrapperForRpcReceiptError,
5 JsonRpcRequestForExperimentalReceipt, JsonRpcRequestForExperimentalReceiptMethod,
6 JsonRpcRequestForLightClientProof, JsonRpcRequestForLightClientProofMethod,
7 JsonRpcRequestForTx, JsonRpcRequestForTxMethod,
8 JsonRpcResponseForRpcLightClientExecutionProofResponseAndRpcLightClientProofError,
9 JsonRpcResponseForRpcReceiptResponseAndRpcReceiptError,
10 JsonRpcResponseForRpcTransactionResponseAndRpcTransactionError,
11 RpcLightClientExecutionProofRequest, RpcLightClientExecutionProofRequestVariant0Type,
12 RpcLightClientExecutionProofResponse, RpcLightClientProofError, RpcReceiptError,
13 RpcReceiptRequest, RpcReceiptResponse, RpcTransactionError, RpcTransactionStatusRequest,
14};
15
16use crate::common::utils::to_retry_error;
17use crate::{
18 NetworkConfig,
19 advanced::RpcType,
20 common::utils::{
21 is_critical_light_client_proof_error, is_critical_receipt_error,
22 is_critical_transaction_status_error,
23 },
24 config::RetryResponse,
25 errors::SendRequestError,
26};
27
28#[derive(Clone, Debug)]
32pub struct TransactionStatusRef {
33 pub sender_account_id: AccountId,
34 pub tx_hash: CryptoHash,
35 pub wait_until: TxExecutionStatus,
36}
37
38#[derive(Clone, Debug)]
42pub struct TransactionStatusRpc;
43
44#[async_trait::async_trait]
45impl RpcType for TransactionStatusRpc {
46 type RpcReference = TransactionStatusRef;
47 type Response = near_openapi_client::types::RpcTransactionResponse;
48 type Error = RpcTransactionError;
49
50 async fn send_query(
51 &self,
52 client: &Client,
53 _network: &NetworkConfig,
54 reference: &TransactionStatusRef,
55 ) -> RetryResponse<Self::Response, SendRequestError<RpcTransactionError>> {
56 let response = client
57 .tx(&JsonRpcRequestForTx {
58 id: "0".to_string(),
59 jsonrpc: "2.0".to_string(),
60 method: JsonRpcRequestForTxMethod::Tx,
61 params: RpcTransactionStatusRequest::Variant1 {
62 sender_account_id: reference.sender_account_id.clone(),
63 tx_hash: reference.tx_hash.into(),
64 wait_until: reference.wait_until,
65 },
66 })
67 .await
68 .map(|r| r.into_inner())
69 .map_err(SendRequestError::from);
70
71 match response {
72 Ok(JsonRpcResponseForRpcTransactionResponseAndRpcTransactionError::Variant0 {
73 result,
74 ..
75 }) => RetryResponse::Ok(result),
76 Ok(JsonRpcResponseForRpcTransactionResponseAndRpcTransactionError::Variant1 {
77 error,
78 ..
79 }) => {
80 let error = SendRequestError::from(error);
81 to_retry_error(error, is_critical_transaction_status_error)
82 }
83 Err(err) => to_retry_error(err, is_critical_transaction_status_error),
84 }
85 }
86}
87
88#[derive(Clone, Debug)]
92pub struct ReceiptRef {
93 pub receipt_id: CryptoHash,
94}
95
96#[derive(Clone, Debug)]
100pub struct ReceiptRpc;
101
102#[async_trait::async_trait]
103impl RpcType for ReceiptRpc {
104 type RpcReference = ReceiptRef;
105 type Response = RpcReceiptResponse;
106 type Error = RpcReceiptError;
107
108 async fn send_query(
109 &self,
110 client: &Client,
111 _network: &NetworkConfig,
112 reference: &ReceiptRef,
113 ) -> RetryResponse<RpcReceiptResponse, SendRequestError<RpcReceiptError>> {
114 let response = client
115 .experimental_receipt(&JsonRpcRequestForExperimentalReceipt {
116 id: "0".to_string(),
117 jsonrpc: "2.0".to_string(),
118 method: JsonRpcRequestForExperimentalReceiptMethod::ExperimentalReceipt,
119 params: RpcReceiptRequest {
120 receipt_id: reference.receipt_id.into(),
121 },
122 })
123 .await
124 .map(|r| r.into_inner())
125 .map_err(SendRequestError::from);
126
127 match response {
128 Ok(JsonRpcResponseForRpcReceiptResponseAndRpcReceiptError::Variant0 {
129 result, ..
130 }) => RetryResponse::Ok(result),
131 Ok(JsonRpcResponseForRpcReceiptResponseAndRpcReceiptError::Variant1 {
132 error, ..
133 }) => {
134 let error = SendRequestError::from(error);
135 to_retry_error(error, is_critical_receipt_error)
136 }
137 Err(err) => to_retry_error(err, is_critical_receipt_error),
138 }
139 }
140}
141
142impl From<ErrorWrapperForRpcReceiptError> for SendRequestError<RpcReceiptError> {
143 fn from(err: ErrorWrapperForRpcReceiptError) -> Self {
144 match err {
145 ErrorWrapperForRpcReceiptError::InternalError(internal_error) => {
146 Self::InternalError(internal_error)
147 }
148 ErrorWrapperForRpcReceiptError::RequestValidationError(
149 rpc_request_validation_error_kind,
150 ) => Self::RequestValidationError(rpc_request_validation_error_kind),
151 ErrorWrapperForRpcReceiptError::HandlerError(server_error) => {
152 Self::ServerError(server_error)
153 }
154 }
155 }
156}
157
158#[derive(Clone, Debug)]
162pub struct TransactionProofRef {
163 pub sender_id: AccountId,
164 pub transaction_hash: CryptoHash,
165 pub light_client_head: CryptoHash,
166}
167
168#[derive(Clone, Debug)]
173pub struct TransactionProofRpc;
174
175#[async_trait::async_trait]
176impl RpcType for TransactionProofRpc {
177 type RpcReference = TransactionProofRef;
178 type Response = RpcLightClientExecutionProofResponse;
179 type Error = RpcLightClientProofError;
180
181 async fn send_query(
182 &self,
183 client: &Client,
184 _network: &NetworkConfig,
185 reference: &TransactionProofRef,
186 ) -> RetryResponse<
187 RpcLightClientExecutionProofResponse,
188 SendRequestError<RpcLightClientProofError>,
189 > {
190 let response = client
191 .light_client_proof(&JsonRpcRequestForLightClientProof {
192 id: "0".to_string(),
193 jsonrpc: "2.0".to_string(),
194 method: JsonRpcRequestForLightClientProofMethod::LightClientProof,
195 params: RpcLightClientExecutionProofRequest::Variant0 {
196 sender_id: reference.sender_id.clone(),
197 transaction_hash: reference.transaction_hash.into(),
198 light_client_head: reference.light_client_head.into(),
199 type_: RpcLightClientExecutionProofRequestVariant0Type::Transaction,
200 },
201 })
202 .await
203 .map(|r| r.into_inner())
204 .map_err(SendRequestError::from);
205
206 match response {
207 Ok(
208 JsonRpcResponseForRpcLightClientExecutionProofResponseAndRpcLightClientProofError::Variant0 {
209 result,
210 ..
211 },
212 ) => RetryResponse::Ok(result),
213 Ok(
214 JsonRpcResponseForRpcLightClientExecutionProofResponseAndRpcLightClientProofError::Variant1 {
215 error,
216 ..
217 },
218 ) => {
219 let error = SendRequestError::from(error);
220 to_retry_error(error, is_critical_light_client_proof_error)
221 }
222 Err(err) => to_retry_error(err, is_critical_light_client_proof_error),
223 }
224 }
225}
226
227impl From<ErrorWrapperForRpcLightClientProofError> for SendRequestError<RpcLightClientProofError> {
228 fn from(err: ErrorWrapperForRpcLightClientProofError) -> Self {
229 match err {
230 ErrorWrapperForRpcLightClientProofError::InternalError(internal_error) => {
231 Self::InternalError(internal_error)
232 }
233 ErrorWrapperForRpcLightClientProofError::RequestValidationError(
234 rpc_request_validation_error_kind,
235 ) => Self::RequestValidationError(rpc_request_validation_error_kind),
236 ErrorWrapperForRpcLightClientProofError::HandlerError(server_error) => {
237 Self::ServerError(server_error)
238 }
239 }
240 }
241}