use reqwest::{Client};
use serde::{Deserialize, Serialize};
use url::Url;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use crate::transaction::types::VidaDataTransaction;
use std::future::Future;
use std::pin::Pin;
pub struct RPC {
pub http_client: Client,
pub node_url: Url,
pub chain_id: u8,
}
#[derive(Debug)]
pub enum RpcError {
FailedToBroadcastTransaction(String),
InvalidRpcUrl,
Network(reqwest::Error),
Deserialization(reqwest::Error),
JsonDeserialization(String),
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BroadcastResponse {
pub success: bool,
pub data: Option<String>,
pub error: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct ResponseData {
pub message: String,
}
#[derive(Serialize)]
pub struct BroadcastRequest {
pub txn: String,
}
pub trait BlockSaver: Send + Sync {
fn save_block(&self, block_number: u64) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>;
}
impl<F> BlockSaver for F
where
F: Fn(u64) + Send + Sync,
{
fn save_block(&self, block_number: u64) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
self(block_number);
Box::pin(async move { })
}
}
pub struct AsyncBlockSaver<F, Fut>
where
F: Fn(u64) -> Fut + Send + Sync,
Fut: Future<Output = ()> + Send,
{
func: F,
}
impl<F, Fut> AsyncBlockSaver<F, Fut>
where
F: Fn(u64) -> Fut + Send + Sync,
Fut: Future<Output = ()> + Send,
{
pub fn new(func: F) -> Self {
Self { func }
}
}
impl<F, Fut> BlockSaver for AsyncBlockSaver<F, Fut>
where
F: Fn(u64) -> Fut + Send + Sync,
Fut: Future<Output = ()> + Send + 'static,
{
fn save_block(&self, block_number: u64) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
Box::pin((self.func)(block_number))
}
}
pub mod block_saver {
use super::*;
use std::future::Future;
pub fn from_sync<F>(func: F) -> Box<dyn BlockSaver>
where
F: Fn(u64) + Send + Sync + 'static,
{
Box::new(func)
}
pub fn from_async<F, Fut>(func: F) -> Box<dyn BlockSaver>
where
F: Fn(u64) -> Fut + Send + Sync + 'static,
Fut: Future<Output = ()> + Send + 'static,
{
Box::new(AsyncBlockSaver::new(func))
}
}
pub struct VidaTransactionSubscription {
pub pwrrs: Arc<RPC>,
pub vida_id: u64,
pub starting_block: u64,
pub poll_interval: u64,
pub latest_checked_block: Arc<std::sync::atomic::AtomicU64>,
pub handler: ProcessVidaTransactions,
pub block_saver: Option<Box<dyn BlockSaver>>,
pub wants_to_pause: Arc<AtomicBool>,
pub paused: Arc<AtomicBool>,
pub stop: Arc<AtomicBool>,
pub running: Arc<AtomicBool>,
}
pub type ProcessVidaTransactions = fn(transaction: VidaDataTransaction);