1#![allow(
4 clippy::type_complexity,
5 clippy::wrong_self_convention,
6 clippy::single_match,
7 clippy::let_unit_value,
8 clippy::match_wild_err_arm
9)]
10#![allow(non_camel_case_types)]
12#![allow(unused_variables)]
13#![allow(dead_code)]
14#![allow(unused_imports)]
15#![recursion_limit = "256"]
17
18use ic_cdk::api::management_canister::http_request::TransformContext;
19use jsonrpc_core as rpc;
20
21#[macro_use]
23pub extern crate futures;
24pub use futures::executor::{block_on, block_on_stream};
25
26pub use ethabi;
27use transports::ic_http_client::CallOptions;
28
29#[macro_use]
32pub mod helpers;
33
34pub mod api;
35pub mod confirm;
36pub mod contract;
37pub mod error;
38pub mod ic;
39pub mod signing;
40pub mod transforms;
41pub mod transports;
42pub mod types;
43pub use crate::{
46 api::Web3,
47 error::{Error, Result},
48};
49
50pub type RequestId = usize;
52
53pub trait Transport: std::fmt::Debug + Clone {
57 type Out: futures::Future<Output = error::Result<rpc::Value>>;
59
60 fn prepare(&self, method: &str, params: Vec<rpc::Value>) -> (RequestId, rpc::Call);
62
63 fn send(&self, id: RequestId, request: rpc::Call, options: CallOptions) -> Self::Out;
65
66 fn execute(&self, method: &str, params: Vec<rpc::Value>, options: CallOptions) -> Self::Out {
68 let (id, request) = self.prepare(method, params);
69 self.send(id, request, options)
70 }
71
72 fn set_max_response_bytes(&mut self, bytes: u64) {}
74}
75
76pub trait BatchTransport: Transport {
78 type Batch: futures::Future<Output = error::Result<Vec<error::Result<rpc::Value>>>>;
80
81 fn send_batch<T>(&self, requests: T) -> Self::Batch
83 where
84 T: IntoIterator<Item = (RequestId, rpc::Call)>;
85}
86
87pub trait DuplexTransport: Transport {
89 type NotificationStream: futures::Stream<Item = rpc::Value>;
91
92 fn subscribe(&self, id: api::SubscriptionId) -> error::Result<Self::NotificationStream>;
94
95 fn unsubscribe(&self, id: api::SubscriptionId) -> error::Result<()>;
97}
98
99impl<X, T> Transport for X
100where
101 T: Transport + ?Sized,
102 X: std::ops::Deref<Target = T>,
103 X: std::fmt::Debug,
104 X: Clone,
105{
106 type Out = T::Out;
107
108 fn prepare(&self, method: &str, params: Vec<rpc::Value>) -> (RequestId, rpc::Call) {
109 (**self).prepare(method, params)
110 }
111
112 fn send(&self, id: RequestId, request: rpc::Call, options: CallOptions) -> Self::Out {
113 (**self).send(id, request, options)
114 }
115}
116
117impl<X, T> BatchTransport for X
118where
119 T: BatchTransport + ?Sized,
120 X: std::ops::Deref<Target = T>,
121 X: std::fmt::Debug,
122 X: Clone,
123{
124 type Batch = T::Batch;
125
126 fn send_batch<I>(&self, requests: I) -> Self::Batch
127 where
128 I: IntoIterator<Item = (RequestId, rpc::Call)>,
129 {
130 (**self).send_batch(requests)
131 }
132}
133
134impl<X, T> DuplexTransport for X
135where
136 T: DuplexTransport + ?Sized,
137 X: std::ops::Deref<Target = T>,
138 X: std::fmt::Debug,
139 X: Clone,
140{
141 type NotificationStream = T::NotificationStream;
142
143 fn subscribe(&self, id: api::SubscriptionId) -> error::Result<Self::NotificationStream> {
144 (**self).subscribe(id)
145 }
146
147 fn unsubscribe(&self, id: api::SubscriptionId) -> error::Result<()> {
148 (**self).unsubscribe(id)
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::{error, rpc, RequestId, Transport};
155
156 use crate::{api::Web3, transports::ic_http_client::CallOptions};
157 use futures::future::BoxFuture;
158 use ic_cdk::api::management_canister::http_request::TransformContext;
159 use std::sync::Arc;
160
161 #[derive(Debug, Clone)]
162 struct FakeTransport;
163
164 impl Transport for FakeTransport {
165 type Out = BoxFuture<'static, error::Result<rpc::Value>>;
166
167 fn prepare(&self, _method: &str, _params: Vec<rpc::Value>) -> (RequestId, rpc::Call) {
168 unimplemented!()
169 }
170
171 fn send(&self, _id: RequestId, _request: rpc::Call, options: CallOptions) -> Self::Out {
172 unimplemented!()
173 }
174 }
175
176 #[test]
177 fn should_allow_to_use_arc_as_transport() {
178 let transport = Arc::new(FakeTransport);
179 let transport2 = transport.clone();
180
181 let _web3_1 = Web3::new(transport);
182 let _web3_2 = Web3::new(transport2);
183 }
184}