Skip to content

Commit 7683a7d

Browse files
committed
feat: estimate_user_operation_gas
1 parent b8be235 commit 7683a7d

File tree

6 files changed

+122
-51
lines changed

6 files changed

+122
-51
lines changed

packages/sdk-platforms/rust/zksync-sso-erc4337/crates/zksync-sso-erc4337-core/src/erc4337/account/modular_smart_account/send.rs

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
use crate::erc4337::account::modular_smart_account::signature::stub_signature;
2-
use crate::erc4337::user_operation::UserOperationV08;
31
use crate::erc4337::{
4-
account::erc7579::{account::Execution, calls::encode_calls},
2+
account::{
3+
erc7579::{account::Execution, calls::encode_calls},
4+
modular_smart_account::signature::stub_signature,
5+
},
56
bundler::pimlico::client::BundlerClient,
7+
entry_point::EntryPoint,
8+
user_operation::hash::v08::get_user_operation_hash_entry_point,
69
};
7-
use alloy::providers::ProviderBuilder;
8-
use alloy::rpc::types::erc4337::PackedUserOperation as AlloyPackedUserOperation;
9-
use alloy::{primitives::Address, providers::Provider};
1010
use alloy::{
11-
primitives::Bytes, rpc::types::erc4337::SendUserOperation,
12-
signers::local::PrivateKeySigner,
11+
primitives::{Address, Bytes},
12+
providers::Provider,
13+
rpc::types::erc4337::{
14+
PackedUserOperation as AlloyPackedUserOperation, SendUserOperation,
15+
},
1316
};
1417
use alloy_provider::ext::Erc4337Api;
15-
use std::str::FromStr;
1618

1719
pub async fn send_transaction<P: Provider + Send + Sync + Clone>(
1820
account: Address,
@@ -33,7 +35,7 @@ pub async fn send_transaction<P: Provider + Send + Sync + Clone>(
3335
// }
3436
// };
3537

36-
let estimated_gas = {
38+
let (estimated_gas, mut user_op) = {
3739
let alloy_user_op = {
3840
let stub_sig = stub_signature(eoa_validator)?;
3941
AlloyPackedUserOperation {
@@ -54,26 +56,26 @@ pub async fn send_transaction<P: Provider + Send + Sync + Clone>(
5456
signature: stub_sig,
5557
}
5658
};
57-
let send_user_op = SendUserOperation::EntryPointV07(alloy_user_op);
58-
let bundler_provider = {
59-
let rpc_url = "http://localhost:4337".parse().unwrap();
60-
61-
let signer_private_key = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
62-
let signer = PrivateKeySigner::from_str(&signer_private_key)?;
63-
let alloy_signer = signer.clone();
64-
let ethereum_wallet =
65-
alloy::network::EthereumWallet::new(alloy_signer.clone());
66-
67-
let provider = ProviderBuilder::new()
68-
.wallet(ethereum_wallet.clone())
69-
.connect_http(rpc_url);
70-
71-
provider
72-
};
73-
74-
bundler_provider
75-
.estimate_user_operation_gas(send_user_op, entry_point)
76-
.await?
59+
let send_user_op =
60+
SendUserOperation::EntryPointV07(alloy_user_op.clone());
61+
// let bundler_provider = {
62+
// let rpc_url = "http://localhost:4337".parse().unwrap();
63+
64+
// let signer_private_key = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
65+
// let signer = PrivateKeySigner::from_str(&signer_private_key)?;
66+
// let alloy_signer = signer.clone();
67+
// let ethereum_wallet =
68+
// alloy::network::EthereumWallet::new(alloy_signer.clone());
69+
70+
// let provider = ProviderBuilder::new()
71+
// .wallet(ethereum_wallet.clone())
72+
// .connect_http(rpc_url);
73+
74+
// provider
75+
// };
76+
// bundler_provider
77+
// .estimate_user_operation_gas(send_user_op, entry_point)
78+
// .await?
7779
// Error: deserialization error: missing field `verificationGas` at line 1 column 158
7880
// {
7981
// "preVerificationGas":"0xbf1a",
@@ -82,14 +84,39 @@ pub async fn send_transaction<P: Provider + Send + Sync + Clone>(
8284
// "paymasterVerificationGasLimit":"0x0",
8385
// "paymasterPostOpGasLimit":"0x0"
8486
// }
85-
8687
// Caused by:
8788
// missing field `verificationGas` at line 1 column 158
89+
90+
let estimated_gas = bundler_client
91+
.estimate_user_operation_gas(&alloy_user_op, &entry_point)
92+
.await?;
93+
94+
(estimated_gas, alloy_user_op)
8895
};
8996

90-
dbg!(estimated_gas);
97+
user_op.call_gas_limit = estimated_gas.callGasLimit;
98+
user_op.verification_gas_limit = estimated_gas.verificationGasLimit;
99+
user_op.pre_verification_gas = estimated_gas.preVerificationGas;
100+
101+
// let packed_user_op = EntryPoint::PackedUserOperation {
102+
// sender: user_op.sender,
103+
// nonce: user_op.nonce,
104+
// initCode: user_op.initCode,
105+
// callData: user_op.callData,
106+
// callGasLimit: user_op.callGasLimit,
107+
// verificationGasLimit: user_op.verificationGasLimit,
108+
// preVerificationGas: user_op.preVerificationGas,
109+
// maxFeePerGas: user_op.maxFeePerGas,
110+
// maxPriorityFeePerGas: user_op.maxPriorityFeePerGas,
111+
// paymasterAndData: user_op.paymasterAndData,
112+
// signature: user_op.signature,
113+
// };
114+
115+
// let hash =
116+
// get_user_operation_hash_entry_point(&user_op, &entry_point, provider)
117+
// .await?;
91118

92-
// bundler_client.estimate_user_operation_gas_price()
119+
// dbg!(estimated_gas);
93120

94121
// let tx = provider.send_transaction(account, encoded_calls).await?;
95122

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod client;
2+
pub mod estimate;
23
pub mod gas_price;

packages/sdk-platforms/rust/zksync-sso-erc4337/crates/zksync-sso-erc4337-core/src/erc4337/bundler/pimlico/client.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
use super::gas_price::GasPrice;
2-
use crate::erc4337::bundler::config::BundlerConfig;
2+
use crate::{
3+
erc4337::bundler::{config::BundlerConfig, pimlico::estimate::Estimate},
4+
jsonrpc::{JSONRPCResponse, Request, Response},
5+
};
6+
use alloy::{
7+
primitives::Address,
8+
rpc::types::erc4337::PackedUserOperation as AlloyPackedUserOperation,
9+
};
310
use eyre::Ok;
11+
use serde_json;
412

513
pub struct BundlerClient {
614
client: reqwest::Client,
@@ -19,9 +27,6 @@ impl BundlerClient {
1927

2028
let bundler_url = self.config.url().clone();
2129

22-
use crate::jsonrpc::{JSONRPCResponse, Request, Response};
23-
use serde_json;
24-
2530
let req_body = Request {
2631
jsonrpc: "2.0".into(),
2732
id: 1,
@@ -50,22 +55,26 @@ impl BundlerClient {
5055

5156
Ok(response_estimate)
5257
}
53-
54-
pub async fn todo(
58+
59+
pub async fn estimate_user_operation_gas(
5560
&self,
56-
) -> eyre::Result<GasPrice> {
57-
println!("estimate_user_operation_gas_price");
61+
user_operation: &AlloyPackedUserOperation,
62+
entry_point: &Address,
63+
) -> eyre::Result<Estimate> {
64+
println!("eth_estimateUserOperationGas");
5865

5966
let bundler_url = self.config.url().clone();
6067

61-
use crate::jsonrpc::{JSONRPCResponse, Request, Response};
62-
use serde_json;
68+
let params = vec![
69+
serde_json::to_value(user_operation)?,
70+
entry_point.to_string().into(),
71+
];
6372

6473
let req_body = Request {
6574
jsonrpc: "2.0".into(),
6675
id: 1,
67-
method: "pimlico_getUserOperationGasPrice".into(),
68-
params: [] as [(); 0],
76+
method: "eth_estimateUserOperationGas".into(),
77+
params,
6978
};
7079
println!("req_body: {:?}", serde_json::to_string(&req_body)?);
7180

@@ -75,14 +84,14 @@ impl BundlerClient {
7584
.json(&req_body)
7685
.send()
7786
.await?;
78-
println!("pimlico_getUserOperationGasPrice post: {:?}", post);
87+
println!("eth_estimateUserOperationGas post: {:?}", post);
7988
let res = post.text().await?;
80-
println!("pimlico_getUserOperationGasPrice res: {:?}", res);
81-
let v = serde_json::from_str::<JSONRPCResponse<GasPrice>>(&res)?;
89+
println!("eth_estimateUserOperationGas res: {:?}", res);
90+
let v = serde_json::from_str::<JSONRPCResponse<Estimate>>(&res)?;
8291

83-
println!("pimlico_getUserOperationGasPrice json: {:?}", v);
92+
println!("eth_estimateUserOperationGas json: {:?}", v);
8493

85-
let response: Response<GasPrice> = v.into();
94+
let response: Response<Estimate> = v.into();
8695

8796
let response_estimate = response?;
8897
let response_estimate = response_estimate.unwrap();
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// {
2+
// "jsonrpc": "2.0",
3+
// "id": 1,
4+
// "result": {
5+
// "preVerificationGas": "0xd3e3",
6+
// "verificationGasLimit": "0x60b01",
7+
// "callGasLimit": "0x13880",
8+
// "paymasterVerificationGasLimit": "0x0",
9+
// "paymasterPostOpGasLimit": "0x0"
10+
// }
11+
// }
12+
13+
use alloy::primitives::U256;
14+
use serde::{Deserialize, Serialize};
15+
16+
#[derive(Debug, Serialize, Deserialize)]
17+
#[serde(rename_all = "camelCase")]
18+
pub struct Estimate {
19+
pub preVerificationGas: U256,
20+
pub verificationGasLimit: U256,
21+
pub callGasLimit: U256,
22+
pub paymasterVerificationGasLimit: U256,
23+
pub paymasterPostOpGasLimit: U256,
24+
}

packages/sdk-platforms/rust/zksync-sso-erc4337/crates/zksync-sso-erc4337-core/src/erc4337/user_operation.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::erc4337::entry_point::PackedUserOperation;
22
use alloy::primitives::{Address, Bytes, FixedBytes, U256};
3-
use alloy::rpc::types::erc4337::PackedUserOperation as AlloyPackedUserOperation;
43
use serde::{Deserialize, Serialize};
54

65
pub mod alloy_helpers;

packages/sdk-platforms/rust/zksync-sso-erc4337/crates/zksync-sso-erc4337-core/src/erc4337/user_operation/hash/v08.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::erc4337::{
2+
entry_point::EntryPoint,
23
entry_point::PackedUserOperation,
34
user_operation::hash::{
45
user_operation_hash::UserOperationHash, v08::pack::CodeReader,
@@ -55,6 +56,16 @@ impl PackedUserOperationWrapper {
5556
}
5657
}
5758

59+
pub async fn get_user_operation_hash_entry_point<P: Provider + Clone>(
60+
user_operation: &PackedUserOperation,
61+
entry_point: &Address,
62+
provider: P,
63+
) -> eyre::Result<UserOperationHash> {
64+
let entry_point = EntryPoint::new(entry_point.clone(), provider.clone());
65+
let hash = entry_point.getUserOpHash(user_operation.clone()).call().await?;
66+
Ok(hash.into())
67+
}
68+
5869
struct NoCodeReader;
5970

6071
impl CodeReader for NoCodeReader {

0 commit comments

Comments
 (0)