zksync_web3_rs/contracts/
main_contract.rs1use std::sync::Arc;
2
3use ethers::prelude::k256::ecdsa::{RecoveryId, Signature};
4use ethers::prelude::k256::schnorr::signature::hazmat::PrehashSigner;
5use ethers::prelude::signer::SignerMiddlewareError;
6use ethers::prelude::ProviderError;
7use ethers::prelude::SignerMiddleware;
8use ethers::providers::Middleware;
9use ethers::signers::Wallet;
10use ethers::types::{Address, Bytes, TransactionReceipt, U256};
11use ethers_contract::{abigen, ContractError};
12
13abigen!(MainContract, "./src/abi/IZkSync.json");
14
15#[derive(thiserror::Error, Debug)]
20pub enum MainContractError<M, D>
21where
22 M: Middleware,
23 D: PrehashSigner<(Signature, RecoveryId)> + Sync + Send,
24{
25 #[error("Middleware error: {0}")]
26 MiddlewareError(#[from] SignerMiddlewareError<M, Wallet<D>>),
27 #[error("Contract error: {0}")]
28 ContractError(#[from] ContractError<SignerMiddleware<M, Wallet<D>>>),
29 #[error("Provider error: {0}")]
30 ProviderError(#[from] ProviderError),
31 #[error("Transaction receipt not found")]
32 TransactionReceiptNotFound,
33}
34
35type SM<M, D> = SignerMiddleware<M, Wallet<D>>;
39
40pub struct MainContractInstance<M, D>
41where
42 M: Middleware,
43 D: PrehashSigner<(Signature, RecoveryId)> + Sync + Send,
44{
45 provider: Arc<SM<M, D>>,
46 contract: MainContract<SM<M, D>>,
47}
48
49impl<M, D> MainContractInstance<M, D>
50where
51 M: Middleware,
52 D: PrehashSigner<(Signature, RecoveryId)> + Sync + Send,
53{
54 pub fn new(address: Address, provider: Arc<SignerMiddleware<M, Wallet<D>>>) -> Self {
55 let contract = MainContract::new(address, Arc::clone(&provider));
56 Self { provider, contract }
57 }
58
59 pub async fn get_base_cost(
60 &self,
61 gas_price: U256,
62 l2_gas_limit: U256,
63 l2_gas_per_pubdata_byte_limit: U256,
64 ) -> Result<U256, ContractError<SM<M, D>>> {
65 self.contract
66 .l_2_transaction_base_cost(gas_price, l2_gas_limit, l2_gas_per_pubdata_byte_limit)
67 .call()
68 .await
69 }
70
71 async fn nonce(&self) -> Result<U256, MainContractError<M, D>> {
72 let signer_address = self.provider.address();
73 let nonce = self
74 .provider
75 .get_transaction_count(signer_address, None)
76 .await?;
77 Ok(nonce)
78 }
79
80 pub async fn request_l2_transaction(
81 &self,
82 contract_l2: Address,
83 l2_value: U256,
84 call_data: Bytes,
85 l2_gas_limit: U256,
86 l2_gas_per_pubdata_byte_limit: U256,
87 factory_deps: Vec<Bytes>,
88 refund_recipient: Address,
89 gas_price: U256,
90 gas_limit: U256,
91 l1_value: U256,
92 ) -> Result<TransactionReceipt, MainContractError<M, D>> {
93 let nonce = self.nonce().await?;
94 let function_call = self
95 .contract
96 .request_l2_transaction(
97 contract_l2,
98 l2_value,
99 call_data,
100 l2_gas_limit,
101 l2_gas_per_pubdata_byte_limit,
102 factory_deps,
103 refund_recipient,
104 )
105 .nonce(nonce)
106 .from(self.provider.address())
107 .gas_price(gas_price)
108 .gas(gas_limit)
109 .value(l1_value);
110 let receipt = function_call
111 .send()
112 .await?
113 .await?
116 .ok_or(MainContractError::<M, D>::TransactionReceiptNotFound)?;
117
118 Ok(receipt)
119 }
120}