diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 738059754..39ebdeb9d 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1742,6 +1742,7 @@ version = "0.1.0" dependencies = [ "async-trait", "ethers", + "eyre", "reqwest", "rustc-hex", "serde", diff --git a/rust/agents/relayer/src/msg/gelato_submitter/sponsored_call_op.rs b/rust/agents/relayer/src/msg/gelato_submitter/sponsored_call_op.rs index aa6627b0b..ed32c391e 100644 --- a/rust/agents/relayer/src/msg/gelato_submitter/sponsored_call_op.rs +++ b/rust/agents/relayer/src/msg/gelato_submitter/sponsored_call_op.rs @@ -213,7 +213,7 @@ impl SponsoredCallOp { sponsor_api_key: &self.sponsor_api_key, }; - Ok(sponsored_call_api_call.run().await?) + sponsored_call_api_call.run().await } fn create_sponsored_call_args(&self) -> SponsoredCallArgs { diff --git a/rust/gelato/Cargo.toml b/rust/gelato/Cargo.toml index 1c0c06749..d44f0510c 100644 --- a/rust/gelato/Cargo.toml +++ b/rust/gelato/Cargo.toml @@ -6,11 +6,12 @@ edition = "2021" [dependencies] async-trait = { version = "0.1", default-features = false } ethers = { git = "https://github.com/abacus-network/ethers-rs", tag = "2022-10-28-01" } +eyre = "0.6" +reqwest = { version = "0", features = ["json"]} +rustc-hex = { version = "2" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", default-features = false } serde_repr = "0.1.9" -tokio = { version = "1", features = ["macros"] } -reqwest = { version = "0", features = ["json"]} -rustc-hex = { version = "2" } thiserror = { version = "1.0", default-features = false } +tokio = { version = "1", features = ["macros"] } tracing = "0.1" diff --git a/rust/gelato/src/lib.rs b/rust/gelato/src/lib.rs index 6b256ce15..08c2c5428 100644 --- a/rust/gelato/src/lib.rs +++ b/rust/gelato/src/lib.rs @@ -1,5 +1,21 @@ +use eyre::eyre; +use reqwest::Response; +use serde::de::DeserializeOwned; + const RELAY_URL: &str = "https://relay.gelato.digital"; pub mod sponsored_call; pub mod task_status; pub mod types; + +async fn parse_response(resp: Response) -> eyre::Result { + let resp_bytes = resp.bytes().await?; + match serde_json::from_slice(&resp_bytes) { + Ok(v) => Ok(v), + Err(e) => { + let text = + String::from_utf8(resp_bytes.into()).unwrap_or_else(|_| "".to_owned()); + Err(eyre!("{}; {}", e, text)) + } + } +} diff --git a/rust/gelato/src/sponsored_call.rs b/rust/gelato/src/sponsored_call.rs index b63108f4e..1300e4724 100644 --- a/rust/gelato/src/sponsored_call.rs +++ b/rust/gelato/src/sponsored_call.rs @@ -1,9 +1,10 @@ -use crate::types::Chain; -use crate::{types::serialize_as_decimal_str, RELAY_URL}; use ethers::types::{Address, Bytes, U256}; use serde::{Deserialize, Serialize}; use tracing::instrument; +use crate::types::Chain; +use crate::{parse_response, types::serialize_as_decimal_str, RELAY_URL}; + #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct SponsoredCallArgs { @@ -13,16 +14,16 @@ pub struct SponsoredCallArgs { // U256 by default serializes as a 0x-prefixed hexadecimal string. // Gelato's API expects the gasLimit to be a decimal string. - /// Skip serializing if None - the Gelato API expects the parameter to either be - /// present as a string, or not at all. + /// Skip serializing if None - the Gelato API expects the parameter to + /// either be present as a string, or not at all. #[serde( serialize_with = "serialize_as_decimal_str", skip_serializing_if = "Option::is_none" )] pub gas_limit: Option, /// If None is provided, the Gelato API will use a default of 5. - /// Skip serializing if None - the Gelato API expects the parameter to either be - /// present as a number, or not at all. + /// Skip serializing if None - the Gelato API expects the parameter to + /// either be present as a number, or not at all. #[serde(skip_serializing_if = "Option::is_none")] pub retries: Option, } @@ -41,14 +42,14 @@ pub struct SponsoredCallApiCallResult { impl<'a> SponsoredCallApiCall<'a> { #[instrument] - pub async fn run(self) -> Result { + pub async fn run(self) -> eyre::Result { let url = format!("{}/relays/v2/sponsored-call", RELAY_URL); let http_args = HTTPArgs { args: self.args, sponsor_api_key: self.sponsor_api_key, }; let res = self.http.post(url).json(&http_args).send().await?; - let result: HTTPResult = res.json().await?; + let result: HTTPResult = parse_response(res).await?; Ok(SponsoredCallApiCallResult::from(result)) } } @@ -110,8 +111,8 @@ mod tests { ), ); - // When the gas limit is specified, ensure it's serialized as a decimal *string*, - // and the retries are a number + // When the gas limit is specified, ensure it's serialized as a decimal + // *string*, and the retries are a number args.gas_limit = Some(U256::from_dec_str("420000").unwrap()); args.retries = Some(5); assert_eq!( diff --git a/rust/gelato/src/task_status.rs b/rust/gelato/src/task_status.rs index a6fb45186..ce5c316b6 100644 --- a/rust/gelato/src/task_status.rs +++ b/rust/gelato/src/task_status.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tracing::instrument; -use crate::RELAY_URL; +use crate::{parse_response, RELAY_URL}; #[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)] pub enum TaskState { @@ -66,10 +66,10 @@ pub struct TaskStatusApiCall { impl TaskStatusApiCall { #[instrument] - pub async fn run(&self) -> Result { + pub async fn run(&self) -> eyre::Result { let url = format!("{}/tasks/status/{}", RELAY_URL, self.args.task_id); let res = self.http.get(url).send().await?; - let result: TaskStatusApiCallResult = res.json().await?; + let result: TaskStatusApiCallResult = parse_response(res).await?; Ok(result) } }