use num_bigint::BigInt;
use reqwest::Method;
use serde::{Deserialize, Deserializer};
use crate::client::request;
use crate::swarm::Error;
use super::DebugApi;
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TransactionInfo {
pub transaction_hash: String,
pub to: String,
pub nonce: u64,
#[serde(default, deserialize_with = "deserialize_opt_bigint")]
pub gas_price: Option<BigInt>,
pub gas_limit: u64,
#[serde(default)]
pub gas_tip_boost: i64,
#[serde(default, deserialize_with = "deserialize_opt_bigint")]
pub gas_tip_cap: Option<BigInt>,
#[serde(default, deserialize_with = "deserialize_opt_bigint")]
pub gas_fee_cap: Option<BigInt>,
#[serde(default)]
pub data: String,
#[serde(default)]
pub created: String,
#[serde(default)]
pub description: String,
#[serde(default, deserialize_with = "deserialize_opt_bigint")]
pub value: Option<BigInt>,
}
fn deserialize_opt_bigint<'de, D>(d: D) -> Result<Option<BigInt>, D::Error>
where
D: Deserializer<'de>,
{
let s: String = Deserialize::deserialize(d)?;
if s.is_empty() {
return Ok(None);
}
s.parse::<BigInt>()
.map(Some)
.map_err(serde::de::Error::custom)
}
impl DebugApi {
pub async fn pending_transactions(&self) -> Result<Vec<TransactionInfo>, Error> {
let builder = request(&self.inner, Method::GET, "transactions")?;
#[derive(Deserialize)]
struct Resp {
#[serde(rename = "pendingTransactions")]
pending_transactions: Vec<TransactionInfo>,
}
let r: Resp = self.inner.send_json(builder).await?;
Ok(r.pending_transactions)
}
pub async fn pending_transaction(&self, tx_hash: &str) -> Result<TransactionInfo, Error> {
let path = format!("transactions/{tx_hash}");
let builder = request(&self.inner, Method::GET, &path)?;
self.inner.send_json(builder).await
}
pub async fn rebroadcast_transaction(&self, tx_hash: &str) -> Result<String, Error> {
let path = format!("transactions/{tx_hash}");
let builder = request(&self.inner, Method::POST, &path)?;
#[derive(Deserialize)]
struct Resp {
#[serde(rename = "transactionHash")]
transaction_hash: String,
}
let r: Resp = self.inner.send_json(builder).await?;
Ok(r.transaction_hash)
}
pub async fn cancel_transaction(
&self,
tx_hash: &str,
gas_price: Option<&BigInt>,
) -> Result<String, Error> {
let path = format!("transactions/{tx_hash}");
let mut builder = request(&self.inner, Method::DELETE, &path)?;
if let Some(gp) = gas_price {
builder = builder.header("gas-price", gp.to_string());
}
#[derive(Deserialize)]
struct Resp {
#[serde(rename = "transactionHash")]
transaction_hash: String,
}
let r: Resp = self.inner.send_json(builder).await?;
Ok(r.transaction_hash)
}
}