From 2af5910cc6715cee31cc54482a33efc156bc3c87 Mon Sep 17 00:00:00 2001 From: imduchuyyy Date: Sat, 22 Jun 2024 09:55:48 +0700 Subject: [PATCH] create passkey module in wallet factory --- script/Deploy.s.sol | 3 --- script/DeployFactory.s.sol | 27 ++++++++++++++++++++++++++ src/WalletFactory.sol | 33 ++++++++++++++++++++++++++++---- src/modules/Passkey.sol | 20 ------------------- test/WalletFactory.t.sol | 2 +- test/modules/PasskeyModule.t.sol | 14 +++++++++----- 6 files changed, 66 insertions(+), 33 deletions(-) create mode 100644 script/DeployFactory.s.sol diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index a494f5a..407cb81 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -21,9 +21,6 @@ contract Deployer is Script { WalletFactory walletFactory = new WalletFactory(address(entryPoint)); console.log("WalletFactory: ", address(walletFactory)); - PasskeyModuleFactory passkeyModuleFactory = new PasskeyModuleFactory(); - console.log("PasskeyModuleFactory: ", address(passkeyModuleFactory)); - vm.stopBroadcast(); } } diff --git a/script/DeployFactory.s.sol b/script/DeployFactory.s.sol new file mode 100644 index 0000000..b24269a --- /dev/null +++ b/script/DeployFactory.s.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache +pragma solidity ^0.8.0; + +import {Script, console2} from "forge-std/Script.sol"; + +import "forge-std/console.sol"; +import "account-abstraction/core/EntryPoint.sol"; +import "../src/WalletFactory.sol"; +import "../src/modules/Passkey.sol"; + +contract Deployer is Script { + function setUp() external {} + + function run() external { + uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY"); + address exitedEntryPoint = vm.envAddress("ENTRY_POINT"); + require(exitedEntryPoint != address(0), "ENTRY_POINT is required"); + vm.startBroadcast(deployerPrivateKey); + + console.log("EntryPoint: ", exitedEntryPoint); + + WalletFactory walletFactory = new WalletFactory(exitedEntryPoint); + console.log("WalletFactory: ", address(walletFactory)); + + vm.stopBroadcast(); + } +} diff --git a/src/WalletFactory.sol b/src/WalletFactory.sol index 6ba3e77..c547b34 100644 --- a/src/WalletFactory.sol +++ b/src/WalletFactory.sol @@ -16,11 +16,9 @@ import "./Wallet.sol"; */ contract WalletFactory is IWalletFactory { Wallet public immutable walletImplement; - PasskeyModuleFactory public immutable passkeyModuleFactory; constructor(address entryPoint) { walletImplement = new Wallet(entryPoint); - passkeyModuleFactory = new PasskeyModuleFactory(); } function _createWallet(address initKey, bytes32 salt) internal returns (Wallet) { @@ -37,22 +35,39 @@ contract WalletFactory is IWalletFactory { } function _createPasskeyModule(uint256 x, uint256 y) internal returns (PasskeyModule) { - address passkeyModuleAddress = passkeyModuleFactory.getPasskeyAddress(x, y); + bytes32 salt = keccak256(abi.encodePacked(x, y)); + address passkeyModuleAddress = getPasskeyAddress(x, y); if (passkeyModuleAddress.code.length > 0) { return PasskeyModule(passkeyModuleAddress); } - return passkeyModuleFactory.create(x, y); + + PasskeyModule passkeyModule = new PasskeyModule{salt: salt}(); + passkeyModule.initialize(x, y); + return passkeyModule; } function createWallet(address initKey, bytes32 salt) external returns (Wallet) { return _createWallet(initKey, salt); } + function createPasskey(uint256 x, uint256 y) external returns (PasskeyModule) { + return _createPasskeyModule(x, y); + } + function createWalletWithPasskey(uint256 x, uint256 y, bytes32 salt) external returns (Wallet) { PasskeyModule passkeyModule = _createPasskeyModule(x, y); return _createWallet(address(passkeyModule), salt); } + function multicall(bytes[] calldata data) external returns (bytes[] memory results) { + results = new bytes[](data.length); + for (uint256 i = 0; i < data.length; i++) { + (bool success, bytes memory result) = address(this).delegatecall(data[i]); + require(success, "Multicall: call failed"); + results[i] = result; + } + } + function getWalletAddress(bytes32 salt) public view returns (address payable) { return payable( Create2.computeAddress( @@ -61,4 +76,14 @@ contract WalletFactory is IWalletFactory { ) ); } + + function getPasskeyAddress(uint256 x, uint256 y) public view returns (address) { + bytes32 salt = keccak256(abi.encodePacked(x, y)); + return payable( + Create2.computeAddress( + salt, + keccak256(type(PasskeyModule).creationCode) + ) + ); + } } diff --git a/src/modules/Passkey.sol b/src/modules/Passkey.sol index 496d5bb..59af3ea 100644 --- a/src/modules/Passkey.sol +++ b/src/modules/Passkey.sol @@ -9,26 +9,6 @@ import "../libraries/Base64Url.sol"; import {WebAuthn} from "../libraries/WebAuthn.sol"; -contract PasskeyModuleFactory { - function create(uint256 x, uint256 y) external returns (PasskeyModule) { - bytes32 salt = keccak256(abi.encodePacked(x, y)); - PasskeyModule passkeyModule = new PasskeyModule{salt: salt}(); - passkeyModule.initialize(x, y); - - return passkeyModule; - } - - function getPasskeyAddress(uint256 x, uint256 y) external view returns (address) { - bytes32 salt = keccak256(abi.encodePacked(x, y)); - return payable( - Create2.computeAddress( - salt, - keccak256(type(PasskeyModule).creationCode) - ) - ); - } -} - contract PasskeyModule is IModule { uint256 public x; uint256 public y; diff --git a/test/WalletFactory.t.sol b/test/WalletFactory.t.sol index a5378a4..844129c 100644 --- a/test/WalletFactory.t.sol +++ b/test/WalletFactory.t.sol @@ -31,7 +31,7 @@ contract WalletFactoryTest is Test { uint256 y = 79473938854726638551736530376995476499049493858003728502280535141260854783821; Wallet wallet = walletFactory.createWalletWithPasskey(x, y, salt); - PasskeyModule passkeyModule = PasskeyModule(walletFactory.passkeyModuleFactory().getPasskeyAddress(x, y)); + PasskeyModule passkeyModule = PasskeyModule(walletFactory.getPasskeyAddress(x, y)); require(wallet.isValidKey(address(passkeyModule)), "passkey module should be valid key"); require(passkeyModule.x() == x, "x should be equal"); diff --git a/test/modules/PasskeyModule.t.sol b/test/modules/PasskeyModule.t.sol index a8dbc64..9f919e5 100644 --- a/test/modules/PasskeyModule.t.sol +++ b/test/modules/PasskeyModule.t.sol @@ -1,17 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.4; +import "account-abstraction/core/EntryPoint.sol"; + import "../../src/modules/Passkey.sol"; import "../../src/libraries/WebAuthn.sol"; +import "../../src/WalletFactory.sol"; import "forge-std/Test.sol"; import "forge-std/console.sol"; contract PasskeyModuleTest is Test { PasskeyModule passkeyModule; - PasskeyModuleFactory passkeyModuleFactory; + WalletFactory walletFactory; function setUp() external { - passkeyModuleFactory = new PasskeyModuleFactory(); + EntryPoint entryPoint = new EntryPoint(); + walletFactory = new WalletFactory(address(entryPoint)); } function testLogPasskeyModuleCreationCodeHash() external view { @@ -19,7 +23,7 @@ contract PasskeyModuleTest is Test { } function testPassKey() external { - passkeyModule = passkeyModuleFactory.create( + passkeyModule = walletFactory.createPasskey( 28203248099655634232680422976510411012986437076966613883671554831358983509938, 79473938854726638551736530376995476499049493858003728502280535141260854783821 ); @@ -35,8 +39,8 @@ contract PasskeyModuleTest is Test { function testComputeAddress() external { uint256 x = 28203248099655634232680422976510411012986437076966613883671554831358983509938; uint256 y = 79473938854726638551736530376995476499049493858003728502280535141260854783821; - address passkeyModuleAddress = passkeyModuleFactory.getPasskeyAddress(x, y); - passkeyModule = passkeyModuleFactory.create(x, y); + address passkeyModuleAddress = walletFactory.getPasskeyAddress(x, y); + passkeyModule = walletFactory.createPasskey(x, y); require(passkeyModuleAddress == address(passkeyModule), "passkey module address should be equal"); }