Account Abstraction, a core technology that enriches user-friendly experiences and security, is at the heart of what we do at Holdstation. We share a similar vision with Vitalik and are here to support growth together.
How to Integrate with Holdstation Gas Station?
Kindly note the following code is our sample. We encourage you to reach out to our dedicated Dev team for assistance. Your seamless integration is our priority!
Copy //// PAYMASTER with EOA Wallet
import { Contract, Provider, types, utils, Wallet } from 'zksync-web3';
import { ethers } from 'ethers';
const PAYMASTER_ADDRESS = '0x8a71416F2BCBd428c3Fc4284404617B139C0181C'
const provider = new Provider(RPC_URL);
const signer = new Wallet(PRIVATE_KEY, provider);
const contract = new Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider)
// method: approve, swap
// ACCOUNT: public address
const populateContract = await contract.populateTransaction[method](...params, {
from: ACCOUNT,
});
const gasLimit = await provider.estimateGas({ ...populatedTx, from: ACCOUNT });
const gasPrice = await provider.getGasPrice();
// TOKEN_ADDRESS: token pay gas erc20
const paymasterParams = utils.getPaymasterParams(PAYMASTER_ADDRESS, {
type: "ApprovalBased",
TOKEN_ADDRESS,
minimalAllowance: ethers.BigNumber.from(1),,
innerInput: new Uint8Array(),
});
populatedTx.customData = {
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT
paymasterParams,
};
const sentTx = await signer.sendTransaction({
...populatedTx,
maxFeePerGas: gasPrice,
maxPriorityFeePerGas: BigNumber.from(0),
gasLimit,
});
Copy //// PAYMASTER with AA Wallet
import { Contract, Provider, types, utils, Wallet } from 'zksync-web3';
import { ethers } from 'ethers';
const PAYMASTER_ADDRESS = '0x8a71416F2BCBd428c3Fc4284404617B139C0181C'
const provider = new Provider(RPC_URL);
const signer = new Wallet(PRIVATE_KEY, provider);
const contract = new Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider)
// method: approve,swap
// ACCOUNT: public address
const populateContract = await contract.populateTransaction[method](...params, {
from: ACCOUNT,
});
const gasLimit = await provider.estimateGas({ ...populatedTx, from: ACCOUNT });
const paymasterParams = utils.getPaymasterParams(PAYMASTER_ADDRESS, {
type: "ApprovalBased",
TOKEN_ADDRESS,
minimalAllowance: ethers.BigNumber.from(1),
innerInput: new Uint8Array(),
});
populatedTx.customData = {
...populatedTx.customData,
paymasterParams: paramsPaymaster,
};
populatedTx.gasLimit = gasLimit;
populatedTx.maxFeePerGas = await provider.getGasPrice();
populatedTx.maxPriorityFeePerGas = ethers.BigNumber.from(0);
populatedTx.chainId = parseInt(CHAIN_ID);
populatedTx.from = ACCOUNT;
populatedTx.nonce = await provider.getTransactionCount(ACCOUNT);
populatedTx.type = 113;
populatedTx.value = ethers.BigNumber.from(0);
populatedTx.customData = {
...populatedTx.customData,
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
} as types.Eip712Meta;
const signature = ethers.utils.arrayify(ethers.utils.joinSignature(await signer.eip712.sign(populatedTx)));
populatedTx.customData = {
...populatedTx.customData,
customSignature: signature,
};
const sendTx = await provider.sendTransaction(utils.serialize(populatedTx));