The purpose of creating the hardhat project was to deploy the contracts and get the contrac's ABI of those contracts and use those Json files in the stackup scripts.
cd Kip-account-abstraction-contract-HH
yarn install
hh compile
hh node
hh run deploy/ <script name> --network mumbai
simple account contract for deploying on testnet and creating user ops.
- escrowedTokens:
- transferring tokens to pool contract.
- withdraw:
- getting back the remained tokens by end-user.
Pool contract's interface.
- using the pool contract functions inside the account abstraction contract.
different vesions of contracts for working with.
Stackup is building the infrastructure needed to transition the world to blockchains.
The user op implementation process in this repository is implemented single and batch.
there are two project in the stackup folder:
- erc-4337
- kip-4337
stackup quickstart project: https://docs.stackup.sh/docs/getting-started
cd Kip-account-abstraction-contract-HH/stackup/kip-4337
yarn install
yarn run dev aa_scripts/<script name>
- generate an smart account for users <script 01>
- increase the smart account balance with kip tokens <script 02>
- approving tokens to AA contract <script 03>
- getting the allowance of smart account and AA contract address <script 04>
- transfer token, calling the function one time and create only one user op <script 05>
- transfer tokens, calling the function multiple time and create several user op <script 06>
- for creating a batch transfer first we need to create a smart account and mint KIP token.
yarn run dev aa_scripts/02-mintKIPTokenWithSmartAccount
- second step is to approve some tokens to Account Abstraction contract.
yarn run dev aa_scripts/03-approveKIPTokenWithSmartAcount
- third step is to check the allowance and make sure that the AA contract has some tokens as approved tokens.
yarn run dev aa_scripts/03-approveKIPTokenWithSmartAcount
- fourth step is to transfer approved tokens to pool contract.(batch transfer)
yarn run dev aa_scripts/06-transferBatchKipToken
rpcUrl is the bundler url, can be received from stackup dashboard. paymasterUrl can be get from the stackup dashboard too.
const rpcUrl = config.rpcUrl;
const paymasterUrl =
"https://api.stackup.sh/v1/paymaster/b51f0843db36f2f091c6fe6b3f1e8e25bb1b52dc7111797924c47e5d63b15fca";
creating a smart account for sending user op
const signingKey = config.PRIVATE_KEY;
const signer = new ethers.Wallet(signingKey);
var builder = await Presets.Builder.SimpleAccount.init(signer, rpcUrl, opts);
const address = builder.getSender();
console.log(`Account address: ${address}`);
AccountContractAddress is the Account Abstraction contract that have been deployed to mumbai. using this address and the contract ABI file we can get the contract it self.
const AccountContractAddress = "0xE90116418c24817C649046075F745525C12b3daA";
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const Account_ABI = require("../abi/AccountAbstraction.json"); // KIP-Token ABI in json format
const AccountContract = new ethers.Contract(AccountContractAddress, Account_ABI, provider);
callTo refers to "where the transaction must be call" we should pass the AA contract address as many time as we want to call a function inside this contract.
const callTo = [
AccountContractAddress,
AccountContractAddress,
AccountContractAddress,
AccountContractAddress,
AccountContractAddress,
];
callData is the list of our calls, if we want to call a function for 5 time we should do like this:
escrowedTokens is a function inside AA contract.
[amount] is the function variable.
const callData = [
AccountContract.interface.encodeFunctionData("escrowedTokens", [amount]),
AccountContract.interface.encodeFunctionData("escrowedTokens", [amount]),
AccountContract.interface.encodeFunctionData("escrowedTokens", [amount]),
AccountContract.interface.encodeFunctionData("escrowedTokens", [amount]),
AccountContract.interface.encodeFunctionData("escrowedTokens", [amount]),
];
at the end we must execute the user operations.
sending the transaction to entryPoint through bundler
const client = await Client.init(rpcUrl);
console.log("going for execute....");
const res = await client.sendUserOperation(
builder.executeBatch(callTo, callData), {
onBuild: (op) => console.log("Signed UserOperation:", op),
});
KIP-4337 project:
mockScript folder contain batch and single user operation with other mock contract like tether(erc-20) , KipToken(erc-20) contracts used for tests