ic_solidity_bindgen/
context.rs

1use crate::Web3Provider;
2use ic_web3_rs::api::Eth;
3use ic_web3_rs::transports::ICHttp;
4use ic_web3_rs::types::Address;
5use ic_web3_rs::Web3;
6use std::sync::Arc;
7
8/// Common data associated with multiple contracts.
9#[derive(Clone)]
10pub struct Web3Context(Arc<Web3ContextInner>);
11
12pub trait Context {
13    type Provider;
14    fn provider(&self, contract: Address, abi: &[u8]) -> Self::Provider;
15}
16
17struct Web3ContextInner {
18    from: Address,
19    // We are not expecting to interact with the chain frequently,
20    // and the websocket transport has problems with ping.
21    // So, the Http transport seems like the best choice.
22    eth: Eth<ICHttp>,
23    chain_id: u64,
24    key_name: String,
25}
26
27impl Web3Context {
28    pub fn new(
29        url: &str,
30        from: Address,
31        chain_id: u64,
32        key_name: String,
33        max_resp: Option<u64>,
34    ) -> Result<Self, ic_web3_rs::error::Error> {
35        let transport = ICHttp::new(url, max_resp)?;
36        let web3 = Web3::new(transport);
37        let eth = web3.eth();
38        let inner = Web3ContextInner {
39            eth,
40            from,
41            chain_id,
42            key_name,
43        };
44        Ok(Self(Arc::new(inner)))
45    }
46
47    pub fn from(&self) -> Address {
48        self.0.from
49    }
50
51    pub(crate) fn eth(&self) -> &Eth<ICHttp> {
52        &self.0.eth
53    }
54    pub fn chain_id(&self) -> u64 {
55        self.0.chain_id
56    }
57
58    pub fn key_name(&self) -> &str {
59        &self.0.key_name
60    }
61}
62
63impl Context for Web3Context {
64    type Provider = Web3Provider;
65    fn provider(&self, contract: Address, json_abi: &[u8]) -> Self::Provider {
66        Web3Provider::new(contract, self, json_abi)
67    }
68}