generated from recmo/rust-service-template
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
644 additions
and
89 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
version: '3' | ||
services: | ||
chain: | ||
image: ghcr.io/foundry-rs/foundry | ||
ports: | ||
- 8545:8545 | ||
command: ["anvil --host 0.0.0.0 --chain-id 31337 --block-time 2 --fork-url https://eth-sepolia.g.alchemy.com/v2/rbe0ZJX0TXJ7udcCB07HHggMt5x5Rcy9@4910128"] | ||
tx-sitter-db: | ||
image: postgres:latest | ||
environment: | ||
- POSTGRES_USER=postgres | ||
- POSTGRES_PASSWORD=postgres | ||
- POSTGRES_DB=tx-sitter | ||
sequencer-db: | ||
image: postgres:latest | ||
environment: | ||
- POSTGRES_USER=postgres | ||
- POSTGRES_PASSWORD=postgres | ||
- POSTGRES_DB=sequencer | ||
tx-sitter: | ||
image: ghcr.io/worldcoin/tx-sitter-monolith:dev | ||
ports: | ||
- 3000:3000 | ||
environment: | ||
- TX_SITTER__SERVICE__ESCALATION_INTERVAL=1m | ||
- TX_SITTER__DATABASE__KIND=connection_string | ||
- TX_SITTER__DATABASE__CONNECTION_STRING=postgres://postgres:postgres@tx-sitter-db:5432/tx-sitter?sslmode=disable | ||
- TX_SITTER__KEYS__KIND=local | ||
- TX_SITTER__PREDEFINED__NETWORK__CHAIN_ID=31337 | ||
- TX_SITTER__PREDEFINED__NETWORK__HTTP_URL=http://chain:8545 | ||
- TX_SITTER__PREDEFINED__NETWORK__WS_URL=ws://chain:8545 | ||
- TX_SITTER__PREDEFINED__RELAYER__ID=1b908a34-5dc1-4d2d-a146-5eb46e975830 | ||
- TX_SITTER__PREDEFINED__RELAYER__CHAIN_ID=31337 | ||
- TX_SITTER__PREDEFINED__RELAYER__KEY_ID=d10607662a85424f02a33fb1e6d095bd0ac7154396ff09762e41f82ff2233aaa | ||
- TX_SITTER__SERVER__HOST=0.0.0.0:3000 | ||
- TX_SITTER__SERVER__DISABLE_AUTH=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "tx-sitter-client" | ||
version = "0.1.0" | ||
edition = "2021" | ||
publish = false | ||
|
||
[dependencies] | ||
anyhow = "1.0" | ||
ethers = { version = "2.0.10", features = [ ] } | ||
reqwest = "0.11.14" | ||
serde = { version = "1.0.154", features = ["derive"] } | ||
serde_json = "1.0.94" | ||
strum = { version = "0.25", features = ["derive"] } | ||
tracing = "0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
use ethers::types::{Address, Bytes, H256, U256}; | ||
use serde::{Deserialize, Serialize}; | ||
use strum::Display; | ||
|
||
mod decimal_u256; | ||
|
||
#[derive(Debug, Default, Clone, Serialize, Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct SendTxRequest { | ||
pub to: Address, | ||
#[serde(with = "decimal_u256")] | ||
pub value: U256, | ||
#[serde(default)] | ||
pub data: Option<Bytes>, | ||
#[serde(with = "decimal_u256")] | ||
pub gas_limit: U256, | ||
#[serde(default)] | ||
pub priority: TransactionPriority, | ||
#[serde(default)] | ||
pub tx_id: Option<String>, | ||
} | ||
|
||
#[derive(Deserialize, Serialize, Debug, Clone, Copy, Default)] | ||
#[serde(rename_all = "camelCase")] | ||
pub enum TransactionPriority { | ||
// 5th percentile | ||
Slowest = 0, | ||
// 25th percentile | ||
Slow = 1, | ||
// 50th percentile | ||
#[default] | ||
Regular = 2, | ||
// 75th percentile | ||
Fast = 3, | ||
// 95th percentile | ||
Fastest = 4, | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct SendTxResponse { | ||
pub tx_id: String, | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct GetTxResponse { | ||
pub tx_id: String, | ||
pub to: Address, | ||
#[serde(default, skip_serializing_if = "Option::is_none")] | ||
pub data: Option<Bytes>, | ||
#[serde(with = "decimal_u256")] | ||
pub value: U256, | ||
#[serde(with = "decimal_u256")] | ||
pub gas_limit: U256, | ||
pub nonce: u64, | ||
|
||
// Sent tx data | ||
#[serde(default, skip_serializing_if = "Option::is_none")] | ||
pub tx_hash: Option<H256>, | ||
pub status: TxStatus, | ||
} | ||
|
||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Display, PartialEq, Eq)] | ||
#[serde(rename_all = "camelCase")] | ||
#[strum(serialize_all = "camelCase")] | ||
pub enum TxStatus { | ||
Unsent, | ||
Pending, | ||
Mined, | ||
Finalized, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
use ethers::types::U256; | ||
|
||
pub fn serialize<S>(u256: &U256, serializer: S) -> Result<S::Ok, S::Error> | ||
where | ||
S: serde::Serializer, | ||
{ | ||
let s = u256.to_string(); | ||
serializer.serialize_str(&s) | ||
} | ||
|
||
pub fn deserialize<'de, D>(deserializer: D) -> Result<U256, D::Error> | ||
where | ||
D: serde::Deserializer<'de>, | ||
{ | ||
let s: &str = serde::Deserialize::deserialize(deserializer)?; | ||
let u256 = U256::from_dec_str(s).map_err(serde::de::Error::custom)?; | ||
Ok(u256) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use serde::{Deserialize, Serialize}; | ||
|
||
use super::*; | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
struct Test { | ||
#[serde(with = "super")] | ||
v: U256, | ||
} | ||
|
||
#[test] | ||
fn test_u256_serde() { | ||
let test = Test { v: U256::from(123) }; | ||
|
||
let s = serde_json::to_string(&test).unwrap(); | ||
assert_eq!(s, r#"{"v":"123"}"#); | ||
|
||
let test: Test = serde_json::from_str(&s).unwrap(); | ||
assert_eq!(test.v, U256::from(123)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use data::{GetTxResponse, SendTxRequest, SendTxResponse, TxStatus}; | ||
use reqwest::Response; | ||
use tracing::instrument; | ||
|
||
pub mod data; | ||
|
||
pub struct TxSitterClient { | ||
client: reqwest::Client, | ||
url: String, | ||
} | ||
|
||
impl TxSitterClient { | ||
pub fn new(url: impl ToString) -> Self { | ||
Self { | ||
client: reqwest::Client::new(), | ||
url: url.to_string(), | ||
} | ||
} | ||
|
||
async fn json_post<T, R>(&self, url: &str, body: T) -> anyhow::Result<R> | ||
where | ||
T: serde::Serialize, | ||
R: serde::de::DeserializeOwned, | ||
{ | ||
let response = self.client.post(url).json(&body).send().await?; | ||
|
||
let response = Self::validate_response(response).await?; | ||
|
||
Ok(response.json().await?) | ||
} | ||
|
||
async fn json_get<R>(&self, url: &str) -> anyhow::Result<R> | ||
where | ||
R: serde::de::DeserializeOwned, | ||
{ | ||
let response = self.client.get(url).send().await?; | ||
|
||
let response = Self::validate_response(response).await?; | ||
|
||
Ok(response.json().await?) | ||
} | ||
|
||
async fn validate_response(response: Response) -> anyhow::Result<Response> { | ||
if !response.status().is_success() { | ||
let status = response.status(); | ||
let body = response.text().await?; | ||
|
||
tracing::error!("Response failed with status {} - {}", status, body); | ||
return Err(anyhow::anyhow!( | ||
"Response failed with status {status} - {body}" | ||
)); | ||
} | ||
|
||
Ok(response) | ||
} | ||
|
||
#[instrument(skip(self))] | ||
pub async fn send_tx(&self, req: &SendTxRequest) -> anyhow::Result<SendTxResponse> { | ||
self.json_post(&format!("{}/tx", self.url), req).await | ||
} | ||
|
||
#[instrument(skip(self))] | ||
pub async fn get_tx(&self, tx_id: &str) -> anyhow::Result<GetTxResponse> { | ||
self.json_get(&format!("{}/tx/{}", self.url, tx_id)).await | ||
} | ||
|
||
#[instrument(skip(self))] | ||
pub async fn get_txs(&self, tx_status: Option<TxStatus>) -> anyhow::Result<Vec<GetTxResponse>> { | ||
let mut url = format!("{}/txs", self.url); | ||
|
||
if let Some(tx_status) = tx_status { | ||
url.push_str(&format!("?status={}", tx_status)); | ||
} | ||
|
||
self.json_get(&url).await | ||
} | ||
|
||
pub fn rpc_url(&self) -> String { | ||
format!("{}/rpc", self.url.clone()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
Oops, something went wrong.