πŸ”„Deploy a custom contract

https://github.com/KintoXYZ/kinto-core/blob/aa/script/test.sol#L101

This script:

  1. Deploys a sample Counter contract using the utility provided by the KintoWalletFactory

  2. Funds the contract through the SponsorPaymaster

  3. Uses the KintoWallet to execute the count() operation through the Kinto AA EntryPoint


Step 1: Similarly to our previous script we initialize all contracts needed and check that AA abstraction is properly deployed.

contract KintoDeployTestCounter is AASetup,KYCSignature, UserOp {

    using ECDSAUpgradeable for bytes32;
    using SignatureChecker for address;

    KintoID _kintoID;
    EntryPoint _entryPoint;
    KintoWalletFactory _walletFactory;
    SponsorPaymaster _sponsorPaymaster;
    IKintoWallet _newWallet;

    function setUp() public {
        uint256 deployerPrivateKey = vm.envUint('TEST_PRIVATE_KEY');
        vm.startBroadcast(deployerPrivateKey);
        (_kintoID, _entryPoint, _walletFactory, _sponsorPaymaster) = _checkAccountAbstraction();
        vm.stopBroadcast();
    }

Step 2: We use the KintoWalletFactory to check that the account already has a wallet and we retrieve it.

    function run() public {
        uint256 deployerPrivateKey = vm.envUint('TEST_PRIVATE_KEY');
        address deployerPublicKey = vm.rememberKey(vm.envUint("TEST_PRIVATE_KEY"));

        console.log('All AA setup is correct');
        vm.startBroadcast(deployerPrivateKey);
        uint salt = 0;
        address newWallet = _walletFactory.getAddress(deployerPublicKey, deployerPublicKey, salt);
        if (!isContract(newWallet)) {
            console.log('ERROR: Wallet not deployed for owner', deployerPublicKey, 'at', newWallet);
            revert();
        }
        _newWallet = IKintoWallet(newWallet);

Step 3: We check and retrieve the Counter if already deployed or use the KintoWalletFactory utility to deploy contracts (deployContract()).

        // Counter contract
        address computed = _walletFactory.getContractAddress(
            bytes32(0), keccak256(abi.encodePacked(type(Counter).creationCode)));
        if (!isContract(computed)) {
            address created = _walletFactory.deployContract(0,
                abi.encodePacked(type(Counter).creationCode), bytes32(0));
            console.log('Deployed Counter contract at', created);
        } else {
            console.log('Counter already deployed at', computed);
        }
        Counter counter = Counter(computed);

Step 4: We check the balance of our Counter contract in the SponsorPaymaster (with balances(address)) and then we addDepositFor{value}(counterAddress).

        
        console.log('Before UserOp. Counter:', counter.count());
        // We add the deposit to the counter contract in the paymaster
        if (_sponsorPaymaster.balances(computed) <= 1e14) {
            _sponsorPaymaster.addDepositFor{value: 5e16}(computed);
            console.log('Adding paymaster balance to counter', computed);
        } else {
            console.log('Counter already has balance to pay for tx', computed);
        }

Step 5: In AA, all operations need to be pack in a UserOperation, we can do this thanks to the KintoWallet.

        // Let's send a transaction to the counter contract through our wallet
        uint startingNonce = _newWallet.getNonce();
        uint256[] memory privateKeys = new uint256[](1);
        privateKeys[0] = deployerPrivateKey;
        UserOperation memory userOp = this.createUserOperationWithPaymasterCustomGas(
            block.chainid,
            address(_newWallet),
            startingNonce,
            privateKeys,
            address(counter),
            0,
            abi.encodeWithSignature('increment()'),
            address(_sponsorPaymaster),
            [uint256(5000000), 3, 3]
        );
        UserOperation[] memory userOps = new UserOperation[](1);
        userOps[0] = userOp;

Step 6: Execute the transaction via the entry point.

        _entryPoint.handleOps(userOps, payable(deployerPublicKey));
        console.log('After UserOp. Counter:', counter.count());
        vm.stopBroadcast();
    }
}

Last updated