Repository navigation
Paymaster with Contract method call? #1146
Team or ProjectNo response Select the SDKRust ZK chainEra Sepolia EnvironmentTestnet Issue DescriptionDon't mean to be a pain, but our team is prototyping for applications that will produce tens or hundreds of millions of transactions. That is why we want to load test and zksync L3. It much easier to do with Rust than TS or JS. Trying to translate the TS below to Rust // Get paymaster params for the Gasless paymaster const fees = await ethers.provider.getFeeData(); // Contribute to the crowdfund contract Expected BehaviorDescription describes. Code ExampleDescribe describes. Repo Link (Optional)No response |
Replies: 1 comment 1 reply
|
Yes, you can do this in Rust. The main difference is that For a contract call, the shape is:
One important detail: for the Roughly like this: use ethers::{
abi::{Address, Token},
prelude::*,
providers::{Http, Provider},
types::U256,
};
use std::{str::FromStr, sync::Arc};
use zksync_web3_rs::{
core::abi::Contract,
eip712::{Eip712Meta, Eip712TransactionRequest, PaymasterParams},
zks_provider::ZKSProvider,
ZKSWallet,
};
const PAYMASTER_ABI: &str = r#"[
{
"inputs": [{"internalType": "bytes", "name": "input", "type": "bytes"}],
"name": "general",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]"#;
let provider = Provider::<Http>::try_from("https://sepolia.era.zksync.dev")?;
let wallet = Wallet::from_str(PRIVATE_KEY)?.with_chain_id(300u64);
let zk_wallet = ZKSWallet::new(wallet, None, Some(provider.clone()), None)?;
let era_provider = zk_wallet.get_era_provider()?;
let contract_fn = Contract::load(MY_CONTRACT_ABI.as_bytes())?
.function("contribute")?;
let calldata = contract_fn.encode_input(&[])?;
let paymaster_fn = Contract::load(PAYMASTER_ABI.as_bytes())?
.function("general")?;
let paymaster_input = paymaster_fn.encode_input(&[Token::Bytes(vec![])])?;
let tx = Eip712TransactionRequest::new()
.from(zk_wallet.l1_wallet.address())
.to(CONTRACT_ADDRESS)
.value(U256::exp10(16)) // 0.01 ETH
.data(calldata)
.custom_data(
Eip712Meta::new().paymaster_params(PaymasterParams {
paymaster: PAYMASTER_ADDRESS,
paymaster_input,
}),
);
let fee = era_provider.estimate_fee(tx.clone()).await?;
let tx = tx
.max_priority_fee_per_gas(0)
.max_fee_per_gas(fee.max_fee_per_gas)
.gas_limit(fee.gas_limit);
let pending = era_provider
.send_transaction_eip712(&zk_wallet.l2_wallet, tx)
.await?;One more thing that is easy to miss: if you use the I checked the type names and method names against |
Yes, you can do this in Rust.
The main difference is that
zksync-web3-rsdoes not give you agetPaymasterParams(...)helper like the TS side. In Rust you build the paymaster part yourself and attach it toEip712Meta.For a contract call, the shape is:
contribute()PaymasterParamsEip712MetaEip712TransactionRequestwithto,value,data, andcustom_dataestimate_feeorzk_estimate_gassend_transaction_eip712One important detail: for the
Generalflow,paymaster_inputis not just an emptyVec<u8>. It should be the ABI-encoded call to the paymaster'sgeneral(bytes)function. The official R…