#![allow(
clippy::type_complexity,
clippy::wrong_self_convention,
clippy::single_match,
clippy::let_unit_value,
clippy::match_wild_err_arm
)]
#![allow(non_camel_case_types)]
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(unused_imports)]
#![recursion_limit = "256"]
use ic_cdk::api::management_canister::http_request::TransformContext;
use jsonrpc_core as rpc;
#[macro_use]
pub extern crate futures;
pub use futures::executor::{block_on, block_on_stream};
pub use ethabi;
use transports::ic_http_client::CallOptions;
#[macro_use]
pub mod helpers;
pub mod api;
pub mod confirm;
pub mod contract;
pub mod error;
pub mod ic;
pub mod signing;
pub mod transforms;
pub mod transports;
pub mod types;
pub use crate::{
api::Web3,
error::{Error, Result},
};
pub type RequestId = usize;
pub trait Transport: std::fmt::Debug + Clone {
type Out: futures::Future<Output = error::Result<rpc::Value>>;
fn prepare(&self, method: &str, params: Vec<rpc::Value>) -> (RequestId, rpc::Call);
fn send(&self, id: RequestId, request: rpc::Call, options: CallOptions) -> Self::Out;
fn execute(&self, method: &str, params: Vec<rpc::Value>, options: CallOptions) -> Self::Out {
let (id, request) = self.prepare(method, params);
self.send(id, request, options)
}
fn set_max_response_bytes(&mut self, bytes: u64) {}
}
pub trait BatchTransport: Transport {
type Batch: futures::Future<Output = error::Result<Vec<error::Result<rpc::Value>>>>;
fn send_batch<T>(&self, requests: T) -> Self::Batch
where
T: IntoIterator<Item = (RequestId, rpc::Call)>;
}
pub trait DuplexTransport: Transport {
type NotificationStream: futures::Stream<Item = rpc::Value>;
fn subscribe(&self, id: api::SubscriptionId) -> error::Result<Self::NotificationStream>;
fn unsubscribe(&self, id: api::SubscriptionId) -> error::Result<()>;
}
impl<X, T> Transport for X
where
T: Transport + ?Sized,
X: std::ops::Deref<Target = T>,
X: std::fmt::Debug,
X: Clone,
{
type Out = T::Out;
fn prepare(&self, method: &str, params: Vec<rpc::Value>) -> (RequestId, rpc::Call) {
(**self).prepare(method, params)
}
fn send(&self, id: RequestId, request: rpc::Call, options: CallOptions) -> Self::Out {
(**self).send(id, request, options)
}
}
impl<X, T> BatchTransport for X
where
T: BatchTransport + ?Sized,
X: std::ops::Deref<Target = T>,
X: std::fmt::Debug,
X: Clone,
{
type Batch = T::Batch;
fn send_batch<I>(&self, requests: I) -> Self::Batch
where
I: IntoIterator<Item = (RequestId, rpc::Call)>,
{
(**self).send_batch(requests)
}
}
impl<X, T> DuplexTransport for X
where
T: DuplexTransport + ?Sized,
X: std::ops::Deref<Target = T>,
X: std::fmt::Debug,
X: Clone,
{
type NotificationStream = T::NotificationStream;
fn subscribe(&self, id: api::SubscriptionId) -> error::Result<Self::NotificationStream> {
(**self).subscribe(id)
}
fn unsubscribe(&self, id: api::SubscriptionId) -> error::Result<()> {
(**self).unsubscribe(id)
}
}
#[cfg(test)]
mod tests {
use super::{error, rpc, RequestId, Transport};
use crate::{api::Web3, transports::ic_http_client::CallOptions};
use futures::future::BoxFuture;
use ic_cdk::api::management_canister::http_request::TransformContext;
use std::sync::Arc;
#[derive(Debug, Clone)]
struct FakeTransport;
impl Transport for FakeTransport {
type Out = BoxFuture<'static, error::Result<rpc::Value>>;
fn prepare(&self, _method: &str, _params: Vec<rpc::Value>) -> (RequestId, rpc::Call) {
unimplemented!()
}
fn send(&self, _id: RequestId, _request: rpc::Call, options: CallOptions) -> Self::Out {
unimplemented!()
}
}
#[test]
fn should_allow_to_use_arc_as_transport() {
let transport = Arc::new(FakeTransport);
let transport2 = transport.clone();
let _web3_1 = Web3::new(transport);
let _web3_2 = Web3::new(transport2);
}
}