solidity_bindgen/
context.rs

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