Skip to content

Instantly share code, notes, and snippets.

@uF4No
Created December 18, 2024 10:31
Show Gist options
  • Save uF4No/1c4e0c68e9490106815ec92c7524446a to your computer and use it in GitHub Desktop.
Save uF4No/1c4e0c68e9490106815ec92c7524446a to your computer and use it in GitHub Desktop.
Script to send an EIP712 transaction via paymaster on ZKsync using Remix
import * as ethers from "ethers";
import {Provider, Contract, utils, Signer, BrowserProvider, Wallet} from "zksync-ethers";
// Address of the ZeekMessages contract
const GREETER_CONTRACT_ADDRESS = "0x2f5Fa95a28EEd40DD80ED3fFC718094EB41253b4";
// Address of the ERC20 token contract
const TOKEN_CONTRACT_ADDRESS = "0xF4dF2c515581A9fA5bAa078d04703c0f3Fd9115a";
// Message to be sent to the contract
const NEW_MESSAGE = "This tx cost me no ETH!";
const GREETER_ABI = [
{
"inputs": [],
"name": "greet",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "string", "name": "_greeting", "type": "string" }],
"name": "setGreeting",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
];
(async () => {
try {
console.log('Sending a transaction via the testnet paymaster')
const browserProvider = new ethers.BrowserProvider(web3Provider)
const signer = await browserProvider.getSigner()
console.log("Signer:", await signer.getAddress());
const zkProvider = new Provider("https://sepolia.era.zksync.dev");
const zkBrowserProvider = new BrowserProvider(web3Provider);
const chainId = Number((await browserProvider.getNetwork()).chainId)
console.log("chain id >> ", chainId)
const zkSigner = Signer.from(await zkBrowserProvider.getSigner(), chainId, zkProvider);
// const zkSigner = Signer.from(signer, , zkProvider);
console.log(`ZK Signer ${await zkSigner.getAddress()}`)
const testnetPaymasterAddress = await zkProvider.getTestnetPaymasterAddress()
console.log(`Testnet paymaster address is ${testnetPaymasterAddress}`);
const gasPrice = await zkProvider.getGasPrice();
console.log("gasPrice is >> ", gasPrice)
// initialise messages and token contracts with address, abi and signer
const messagesContract= new Contract(GREETER_CONTRACT_ADDRESS, GREETER_ABI, zkSigner);
// define paymaster parameters for gas estimation
const paramsForFeeEstimation = utils.getPaymasterParams(testnetPaymasterAddress, {
type: "ApprovalBased",
token: TOKEN_CONTRACT_ADDRESS,
// set minimalAllowance to 1 for estimation
minimalAllowance: 1n,
// empty bytes as testnet paymaster does not use innerInput
innerInput: new Uint8Array(0),
});
console.log(paramsForFeeEstimation)
// estimate gasLimit via paymaster
const gasLimit = await messagesContract.setGreeting.estimateGas(NEW_MESSAGE, {
customData: {
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
paymasterParams: paramsForFeeEstimation,
},
});
console.log("gasLimit is >> ", gasLimit)
// fee calculated in ETH will be the same in
// ERC20 token using the testnet paymaster
const fee = gasPrice * gasLimit;
console.log("Fee is >>", fee);
// new paymaster params with fee as minimalAllowance
const paymasterParams = utils.getPaymasterParams(testnetPaymasterAddress, {
type: "ApprovalBased",
token: TOKEN_CONTRACT_ADDRESS,
// provide estimated fee as allowance
minimalAllowance: fee,
// minimalAllowance: 1n,
// empty bytes as testnet paymaster does not use innerInput
innerInput: new Uint8Array(0),
});
// full overrides object including maxFeePerGas and maxPriorityFeePerGas
const txOverrides = {
maxFeePerGas: gasPrice,
maxPriorityFeePerGas: "1",
// hardcoded
// gasLimit: 600000,
gasLimit,
customData: {
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
paymasterParams,
}
}
console.log(`Sending tx via your wallet`);
// send transaction with additional paymaster params as overrides
const txHandle = await messagesContract.setGreeting(NEW_MESSAGE, txOverrides);
await txHandle.wait();
console.log(`Transaction processed`)
console.log(`Done!`);
} catch (e) {
console.error('Error in script!')
console.error(e.message)
console.error(e)
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment