1use std::sync::Arc;
2
3use async_trait::async_trait;
4use aws_sdk_lambda::primitives::Blob;
5use ethers::providers::JsonRpcClient;
6use serde::de::DeserializeOwned;
7use serde::Serialize;
8
9use self::error::ClientError;
10use super::TxSitterInner;
11use crate::rpc::data::{JsonRpcResponse, JsonRpcVersion, RpcLambdaRequest, RpcPayload};
12
13pub mod data;
14pub mod error;
15
16#[derive(Clone, Debug)]
17pub struct TxSitterRpcClient {
18 relayer_id: String,
19 inner: Arc<TxSitterInner>,
20}
21
22impl TxSitterRpcClient {
23 pub(super) fn new(relayer_id: String, inner: Arc<TxSitterInner>) -> Self {
24 Self { relayer_id, inner }
25 }
26}
27
28#[async_trait]
29impl JsonRpcClient for TxSitterRpcClient {
30 type Error = ClientError;
31
32 async fn request<T, R>(&self, method: &str, params: T) -> Result<R, Self::Error>
34 where
35 T: std::fmt::Debug + Serialize + Send + Sync,
36 R: DeserializeOwned + Send,
37 {
38 let payload = RpcPayload {
39 id: 1,
40 method: method.into(),
41 params: serde_json::to_value(params)?,
42 jsonrpc: JsonRpcVersion::V2,
43 };
44
45 let lambda_request = RpcLambdaRequest {
46 payload,
47 relayer_id: self.relayer_id.clone(),
48 };
49
50 let payload = serde_json::to_vec(&lambda_request)?;
51
52 let res = self
53 .inner
54 .client
55 .invoke()
56 .function_name(self.inner.config.rpc_lambda_name.clone())
57 .payload(Blob::new(payload))
58 .send()
59 .await?;
60
61 let payload = res.payload.ok_or(ClientError::MissingPayload)?;
62
63 let result: JsonRpcResponse<R> = serde_json::from_slice(&payload.into_inner())?;
64
65 match (result.result, result.error) {
66 (Some(result), None) => Ok(result),
67 (None, Some(error)) => Err(ClientError::Rpc(error)),
68 _ => Err(ClientError::Other(
69 "Invalid response from the RPC".to_string(),
70 )),
71 }
72 }
73}