Skip to content
This repository has been archived by the owner on Dec 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #19 from abstraction-hq/18-create-passkey-in-walle…
Browse files Browse the repository at this point in the history
…t-factory

create passkey module in wallet factory
  • Loading branch information
imduchuyyy authored Jun 22, 2024
2 parents 0c2ceac + 2af5910 commit 3b6cd14
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 33 deletions.
3 changes: 0 additions & 3 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
27 changes: 27 additions & 0 deletions script/DeployFactory.s.sol
Original file line number Diff line number Diff line change
@@ -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();
}
}
33 changes: 29 additions & 4 deletions src/WalletFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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(
Expand All @@ -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)
)
);
}
}
20 changes: 0 additions & 20 deletions src/modules/Passkey.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion test/WalletFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
14 changes: 9 additions & 5 deletions test/modules/PasskeyModule.t.sol
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
// 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 {
console.logBytes32(keccak256(type(PasskeyModule).creationCode));
}

function testPassKey() external {
passkeyModule = passkeyModuleFactory.create(
passkeyModule = walletFactory.createPasskey(
28203248099655634232680422976510411012986437076966613883671554831358983509938,
79473938854726638551736530376995476499049493858003728502280535141260854783821
);
Expand All @@ -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");
}
Expand Down

0 comments on commit 3b6cd14

Please sign in to comment.