diff --git a/packages/auth-server/stores/client.ts b/packages/auth-server/stores/client.ts index b258c17d..fe2b8a84 100644 --- a/packages/auth-server/stores/client.ts +++ b/packages/auth-server/stores/client.ts @@ -28,9 +28,9 @@ export const contractsByChain: Record = { }, [zksyncInMemoryNode.id]: { session: "0x8543528a4561E3a5EC7d51Bfd3776457b0E7b7dc", - passkey: "0x07734BA326b6AD13BfC0115b0903EB14268F1617", + passkey: "0x975df0c7f5CB728ae9F96480491Ec5d1E17296f4", accountFactory: "0xaAF5f437fB0524492886fbA64D703df15BF619AE", - accountPaymaster: "0x2879853afd8d066ca66e224A8E85621aC43d6F59", + accountPaymaster: "0x351cB880A2B9E1Cf3060ea58Ec5280CBCe87579A", }, }; diff --git a/packages/contracts/src/AAFactory.sol b/packages/contracts/src/AAFactory.sol index ed24634d..442b2dca 100644 --- a/packages/contracts/src/AAFactory.sol +++ b/packages/contracts/src/AAFactory.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.24; import "@matterlabs/zksync-contracts/l2/system-contracts/Constants.sol"; import "@matterlabs/zksync-contracts/l2/system-contracts/libraries/SystemContractsCaller.sol"; -import { IClaveAccount } from "./interfaces/IClaveAccount.sol"; +import { ISsoAccount } from "./interfaces/ISsoAccount.sol"; import { UpgradeableBeacon } from "./UpgradeableBeacon.sol"; import "./helpers/Logger.sol"; @@ -19,14 +19,22 @@ contract AAFactory is UpgradeableBeacon { beaconProxyBytecodeHash = _beaconProxyBytecodeHash; } - function addNewUniqueId(bytes32 uniqueAccountId) external {} - function deployProxy7579Account( bytes32 salt, string calldata uniqueAccountId, bytes[] calldata initialValidators, bytes[] calldata initialModules, address[] calldata initialK1Owners + ) external returns (address) { + return this.deployProxySsoAccount(salt, uniqueAccountId, initialValidators, initialModules, initialK1Owners); + } + + function deployProxySsoAccount( + bytes32 salt, + string calldata uniqueAccountId, + bytes[] calldata initialValidators, + bytes[] calldata initialModules, + address[] calldata initialK1Owners ) external returns (address accountAddress) { (bool success, bytes memory returnData) = SystemContractsCaller.systemCallWithReturndata( uint32(gasleft()), @@ -50,7 +58,7 @@ contract AAFactory is UpgradeableBeacon { Logger.logAddress(accountAddress); // add session-key/spend-limit module (similar code) - IClaveAccount(accountAddress).initialize(initialValidators, initialModules, initialK1Owners); + ISsoAccount(accountAddress).initialize(initialValidators, initialModules, initialK1Owners); if (accountMappings[uniqueAccountId] != address(0)) { revert("Account already exists"); diff --git a/packages/contracts/src/ERC7579Account.sol b/packages/contracts/src/ERC7579Account.sol deleted file mode 100644 index 0ea9de20..00000000 --- a/packages/contracts/src/ERC7579Account.sol +++ /dev/null @@ -1,289 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "./libraries/ERC7579Mode.sol"; - -import "./interfaces/IERC7579Module.sol"; -import "./interfaces/IERC7579Validator.sol"; - -import { BOOTLOADER_FORMAL_ADDRESS } from "@matterlabs/zksync-contracts/l2/system-contracts/Constants.sol"; -import { IAccount } from "@matterlabs/zksync-contracts/l2/system-contracts/interfaces/IAccount.sol"; -import { EfficientCall } from "@matterlabs/zksync-contracts/l2/system-contracts/libraries/EfficientCall.sol"; - -import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; - -import { Call } from "./batch/BatchCaller.sol"; - -import { IERC7579Account } from "./interfaces/IERC7579Account.sol"; -import { ModuleManager } from "./managers/ModuleManager.sol"; -import { HookManager } from "./managers/HookManager.sol"; -import { ExecutionHelper } from "./helpers/Execution.sol"; - -import { ClaveAccount } from "./ClaveAccount.sol"; -import { PackedUserOperation } from "./interfaces/PackedUserOperation.sol"; - -/** - * @author zeroknots.eth | rhinestone.wtf - * Reference implementation of a very simple ERC7579 Account. - * This account implements CallType: SINGLE, BATCH and DELEGATECALL. - * This account implements ExecType: DEFAULT and TRY. - * Hook support is implemented - */ -contract ERC7579Account is IERC7579Account, HookManager, ModuleManager, ExecutionHelper, ClaveAccount { - using ModeLib for ModeCode; - error AccountAccessUnauthorized(); - // Error thrown when an unsupported ModuleType is requested - error UnsupportedModuleType(uint256 moduleTypeId); - // Error thrown when an execution with an unsupported CallType was made - error UnsupportedCallType(CallType callType); - // Error thrown when an execution with an unsupported ExecType was made - error UnsupportedExecType(ExecType execType); - // Error thrown when account initialization fails - error AccountInitializationFailed(); - // Error thrown when account installs/unistalls module with mismatched input `moduleTypeId` - error MismatchModuleTypeId(uint256 moduleTypeId); - - bytes4 constant EIP1271_SUCCESS_RETURN_VALUE = 0x1626ba7e; - address private _factory = address(0); - - ///////////////////////////////////////////////////// - // Access Control - //////////////////////////////////////////////////// - - modifier onlyEntryPointOrSelf() virtual { - if (!(msg.sender == BOOTLOADER_FORMAL_ADDRESS || msg.sender == address(this) || msg.sender == _factory)) { - revert AccountAccessUnauthorized(); - } - _; - } - - modifier onlyEntryPoint() virtual { - if (msg.sender != BOOTLOADER_FORMAL_ADDRESS) { - revert AccountAccessUnauthorized(); - } - _; - } - - /** - * @inheritdoc IERC7579Account - * @dev this function is only callable by the entry point or the account itself - * @dev this function demonstrates how to implement - * CallType SINGLE and BATCH and ExecType DEFAULT and TRY - * @dev this function demonstrates how to implement hook support (modifier) - */ - function execute(ModeCode mode, bytes calldata executionCalldata) external payable onlyEntryPointOrSelf withHook { - (CallType callType, ExecType execType, , ) = mode.decode(); - - // check if calltype is batch or single - if (keccak256(abi.encodePacked(callType)) == keccak256(abi.encodePacked(CALLTYPE_BATCH))) { - // destructure executionCallData according to batched exec - Execution[] calldata executions = decodeBatch(executionCalldata); - // check if execType is revert or try - if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_DEFAULT)) _execute(executions); - else if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_TRY)) _tryExecute(executions); - else revert UnsupportedExecType(execType); - } else if (CallType.unwrap(callType) == CallType.unwrap(CALLTYPE_SINGLE)) { - // destructure executionCallData according to single exec - (address target, uint256 value, bytes calldata callData) = decodeSingle(executionCalldata); - // check if execType is revert or try - if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_DEFAULT)) - _execute(target, value, callData); - // TODO: implement event emission for tryExecute singleCall - else if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_TRY)) _tryExecute(target, value, callData); - else revert UnsupportedExecType(execType); - } else if (CallType.unwrap(callType) == CallType.unwrap(CALLTYPE_DELEGATECALL)) { - // destructure executionCallData according to single exec - address delegate = address(uint160(bytes20(executionCalldata[0:20]))); - bytes calldata callData = executionCalldata[20:]; - // check if execType is revert or try - if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_DEFAULT)) _executeDelegatecall(delegate, callData); - else if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_TRY)) _tryExecuteDelegatecall(delegate, callData); - else revert UnsupportedExecType(execType); - } else { - revert UnsupportedCallType(callType); - } - } - - /** - * @inheritdoc IERC7579Account - * @dev this function is only callable by an installed executor module - * @dev this function demonstrates how to implement - * CallType SINGLE and BATCH and ExecType DEFAULT and TRY - * @dev this function demonstrates how to implement hook support (modifier) - */ - function executeFromExecutor( - ModeCode mode, - bytes calldata executionCalldata - ) - external - payable - withHook - returns ( - bytes[] memory returnData // TODO returnData is not used - ) - { - (CallType callType, ExecType execType, , ) = mode.decode(); - - // check if calltype is batch or single - if (CallType.unwrap(callType) == CallType.unwrap(CALLTYPE_BATCH)) { - // destructure executionCallData according to batched exec - Execution[] calldata executions = decodeBatch(executionCalldata); - // check if execType is revert or try - if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_DEFAULT)) returnData = _execute(executions); - else if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_TRY)) returnData = _tryExecute(executions); - else revert UnsupportedExecType(execType); - } else if (CallType.unwrap(callType) == CallType.unwrap(CALLTYPE_SINGLE)) { - // destructure executionCallData according to single exec - (address target, uint256 value, bytes calldata callData) = decodeSingle(executionCalldata); - returnData = new bytes[](1); - bool success; - // check if execType is revert or try - if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_DEFAULT)) { - returnData[0] = _execute(target, value, callData); - } - // TODO: implement event emission for tryExecute singleCall - else if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_TRY)) { - (success, returnData[0]) = _tryExecute(target, value, callData); - if (!success) emit TryExecuteUnsuccessful(0, returnData[0]); - } else { - revert UnsupportedExecType(execType); - } - } else if (CallType.unwrap(callType) == CallType.unwrap(CALLTYPE_DELEGATECALL)) { - // destructure executionCallData according to single exec - address delegate = address(uint160(bytes20(executionCalldata[0:20]))); - bytes calldata callData = executionCalldata[20:]; - // check if execType is revert or try - if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_DEFAULT)) _executeDelegatecall(delegate, callData); - else if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_TRY)) _tryExecuteDelegatecall(delegate, callData); - else revert UnsupportedExecType(execType); - } else { - revert UnsupportedCallType(callType); - } - } - - /** - * @inheritdoc IERC7579Account - */ - function installModule( - uint256 moduleTypeId, - address module, - bytes calldata initData - ) external payable onlyEntryPointOrSelf withHook { - if (!IERC7579Module(module).isModuleType(moduleTypeId)) revert MismatchModuleTypeId(moduleTypeId); - - if (moduleTypeId == MODULE_TYPE_VALIDATOR) _addUserOpValidator(module, initData); - else if (moduleTypeId == MODULE_TYPE_EXECUTOR) _addExternalExecutorPermission(module, initData); - else if (moduleTypeId == MODULE_TYPE_FALLBACK) _addFallbackModule(module, initData); - else if (moduleTypeId == MODULE_TYPE_HOOK) _installHook(module, initData); - else revert UnsupportedModuleType(moduleTypeId); - emit ModuleInstalled(moduleTypeId, module); - } - - /** - * @inheritdoc IERC7579Account - */ - function uninstallModule( - uint256 moduleTypeId, - address module, - bytes calldata deInitData - ) external payable onlyEntryPointOrSelf withHook { - if (moduleTypeId == MODULE_TYPE_VALIDATOR) { - _uninstallValidator(module, deInitData); - } else if (moduleTypeId == MODULE_TYPE_EXECUTOR) { - _removeExternalExecutorModule(module, deInitData); - } else if (moduleTypeId == MODULE_TYPE_FALLBACK) { - _removeFallbackModule(module, deInitData); - } else if (moduleTypeId == MODULE_TYPE_HOOK) { - _uninstallHook(module, deInitData); - } else { - revert UnsupportedModuleType(moduleTypeId); - } - emit ModuleUninstalled(moduleTypeId, module); - } - - /** - * @dev ERC-4337 validateUserOp according to ERC-4337 v0.7 - * This function is intended to be called by ERC-4337 EntryPoint.sol - * this validation function should decode / sload the validator module to validate the userOp - * and call it. - * - * @dev MSA MUST implement this function signature. - * @param userOp PackedUserOperation struct (see ERC-4337 v0.7+) - */ - function validateUserOp( - PackedUserOperation calldata userOp, - bytes32 userOpHash, - uint256 missingAccountFunds - ) external payable virtual onlyEntryPoint returns (uint256 validSignature) { - address validator; - // @notice validator encoding in nonce is just an example! - // @notice this is not part of the standard! - // Account Vendors may choose any other way to implement validator selection - uint256 nonce = userOp.nonce; - assembly { - validator := shr(96, nonce) - } - - // bubble up the return value of the validator module - validSignature = IUserOpValidator(validator).validateUserOp(userOp, userOpHash); - } - - /** - * @inheritdoc IERC7579Account - */ - function isModuleInstalled( - uint256 moduleTypeId, - address module, - bytes calldata additionalContext - ) external view override returns (bool) { - if (moduleTypeId == MODULE_TYPE_VALIDATOR) { - return _isModule(module); - } else if (moduleTypeId == MODULE_TYPE_EXECUTOR) { - return _isModule(module); - } else if (moduleTypeId == MODULE_TYPE_FALLBACK) { - return _isModule(module); - } else if (moduleTypeId == MODULE_TYPE_HOOK) { - return _isHook(module); - } else { - return false; - } - } - - /** - * @inheritdoc IERC7579Account - */ - function supportsExecutionMode(ModeCode mode) external view virtual override returns (bool isSupported) { - (CallType callType, ExecType execType, , ) = mode.decode(); - if (CallType.unwrap(callType) == CallType.unwrap(CALLTYPE_BATCH)) isSupported = true; - else if (CallType.unwrap(callType) == CallType.unwrap(CALLTYPE_SINGLE)) isSupported = true; - else if (CallType.unwrap(callType) == CallType.unwrap(CALLTYPE_DELEGATECALL)) - isSupported = true; - // if callType is not single, batch or delegatecall return false - else return false; - - if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_DEFAULT)) isSupported = true; - else if (ExecType.unwrap(execType) == ExecType.unwrap(EXECTYPE_TRY)) - isSupported = true; - // if execType is not default or try, return false - else return false; - } - - /** - * @inheritdoc IERC7579Account - */ - function supportsModule(uint256 moduleTypeId) external view virtual override returns (bool) { - if (moduleTypeId == MODULE_TYPE_VALIDATOR) return true; - else if (moduleTypeId == MODULE_TYPE_EXECUTOR) return true; - else if (moduleTypeId == MODULE_TYPE_FALLBACK) return true; - else if (moduleTypeId == MODULE_TYPE_HOOK) return true; - else return false; - } - - /** - * @inheritdoc IERC7579Account - */ - function accountId() external view virtual override returns (string memory) { - // vendor.flavour.SemVer - return "zksync.default.v0.1"; - } -} diff --git a/packages/contracts/src/ClaveAccount.sol b/packages/contracts/src/SsoAccount.sol similarity index 97% rename from packages/contracts/src/ClaveAccount.sol rename to packages/contracts/src/SsoAccount.sol index f98414c0..0fb78d04 100644 --- a/packages/contracts/src/ClaveAccount.sol +++ b/packages/contracts/src/SsoAccount.sol @@ -23,7 +23,7 @@ import { ModeCode } from "./libraries/ERC7579Mode.sol"; import { ERC1271Handler } from "./handlers/ERC1271Handler.sol"; import { BatchCaller } from "./batch/BatchCaller.sol"; -import { IClaveAccount } from "./interfaces/IClaveAccount.sol"; +import { ISsoAccount } from "./interfaces/ISsoAccount.sol"; import "./helpers/Logger.sol"; @@ -32,7 +32,7 @@ import "./helpers/Logger.sol"; * @author https://getclave.io */ -contract ClaveAccount is +contract SsoAccount is Initializable, UpgradeManager, HookManager, @@ -40,7 +40,7 @@ contract ClaveAccount is ERC1271Handler, TokenCallbackHandler, BatchCaller, - IClaveAccount + ISsoAccount { // Helper library for the Transaction struct using TransactionHelper for Transaction; @@ -201,9 +201,9 @@ contract ClaveAccount is transaction.processPaymasterInput(); } - /// @dev type(IClave).interfaceId indicates Clave accounts + /// @dev type(ISsoAccount).interfaceId indicates SSO accounts function supportsInterface(bytes4 interfaceId) public view override(IERC165, TokenCallbackHandler) returns (bool) { - return interfaceId == type(IClaveAccount).interfaceId || super.supportsInterface(interfaceId); + return interfaceId == type(ISsoAccount).interfaceId || super.supportsInterface(interfaceId); } function _validateTransaction( diff --git a/packages/contracts/src/helpers/Execution.sol b/packages/contracts/src/helpers/Execution.sol deleted file mode 100644 index 70575169..00000000 --- a/packages/contracts/src/helpers/Execution.sol +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import { Execution } from "../interfaces/IERC7579Account.sol"; - -/** - * @title Execution - * @dev This contract executes calls in the context of this contract. - * @author zeroknots.eth | rhinestone.wtf - * shoutout to solady (vectorized, ross) for this code - * https://github.com/Vectorized/solady/blob/main/src/accounts/ERC4337.sol - */ -contract ExecutionHelper { - error ExecutionFailed(); - - event TryExecuteUnsuccessful(uint256 batchExecutionindex, bytes result); - - function decodeBatch(bytes calldata callData) internal pure returns (Execution[] calldata executionBatch) { - /* - * Batch Call Calldata Layout - * Offset (in bytes) | Length (in bytes) | Contents - * 0x0 | 0x4 | bytes4 function selector - * 0x4 | - | - abi.encode(IERC7579Execution.Execution[]) - */ - // solhint-disable-next-line no-inline-assembly - assembly ("memory-safe") { - let dataPointer := add(callData.offset, calldataload(callData.offset)) - - // Extract the ERC7579 Executions - executionBatch.offset := add(dataPointer, 32) - executionBatch.length := calldataload(dataPointer) - } - } - - function encodeBatch(Execution[] memory executions) internal pure returns (bytes memory callData) { - callData = abi.encode(executions); - } - - function decodeSingle( - bytes calldata executionCalldata - ) internal pure returns (address target, uint256 value, bytes calldata callData) { - target = address(bytes20(executionCalldata[0:20])); - value = uint256(bytes32(executionCalldata[20:52])); - callData = executionCalldata[52:]; - } - - function encodeSingle( - address target, - uint256 value, - bytes memory callData - ) internal pure returns (bytes memory userOpCalldata) { - userOpCalldata = abi.encodePacked(target, value, callData); - } - - function _execute(Execution[] calldata executions) internal returns (bytes[] memory result) { - uint256 length = executions.length; - result = new bytes[](length); - - for (uint256 i; i < length; i++) { - Execution calldata _exec = executions[i]; - result[i] = _execute(_exec.target, _exec.value, _exec.callData); - } - } - - function _tryExecute(Execution[] calldata executions) internal returns (bytes[] memory result) { - uint256 length = executions.length; - result = new bytes[](length); - - for (uint256 i; i < length; i++) { - Execution calldata _exec = executions[i]; - bool success; - (success, result[i]) = _tryExecute(_exec.target, _exec.value, _exec.callData); - if (!success) emit TryExecuteUnsuccessful(i, result[i]); - } - } - - function _execute( - address target, - uint256 value, - bytes calldata callData - ) internal virtual returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - calldatacopy(result, callData.offset, callData.length) - if iszero(call(gas(), target, value, result, callData.length, codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(result, 0x00, returndatasize()) - revert(result, returndatasize()) - } - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } - - function _tryExecute( - address target, - uint256 value, - bytes calldata callData - ) internal virtual returns (bool success, bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - calldatacopy(result, callData.offset, callData.length) - success := call(gas(), target, value, result, callData.length, codesize(), 0x00) - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } - - /// @dev Execute a delegatecall with `delegate` on this account. - function _executeDelegatecall(address delegate, bytes calldata callData) internal returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - calldatacopy(result, callData.offset, callData.length) - // Forwards the `data` to `delegate` via delegatecall. - if iszero(delegatecall(gas(), delegate, result, callData.length, codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(result, 0x00, returndatasize()) - revert(result, returndatasize()) - } - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } - - /// @dev Execute a delegatecall with `delegate` on this account and catch reverts. - function _tryExecuteDelegatecall( - address delegate, - bytes calldata callData - ) internal returns (bool success, bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - calldatacopy(result, callData.offset, callData.length) - // Forwards the `data` to `delegate` via delegatecall. - success := delegatecall(gas(), delegate, result, callData.length, codesize(), 0x00) - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } -} diff --git a/packages/contracts/src/interfaces/IERC7579Account.sol b/packages/contracts/src/interfaces/IERC7579Account.sol deleted file mode 100644 index ad22ff9d..00000000 --- a/packages/contracts/src/interfaces/IERC7579Account.sol +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import { CallType, ExecType, ModeCode } from "../libraries/ERC7579Mode.sol"; - -struct Execution { - address target; - uint256 value; - bytes callData; -} - -interface IERC7579Account { - event ModuleInstalled(uint256 moduleTypeId, address module); - event ModuleUninstalled(uint256 moduleTypeId, address module); - - /** - * @dev Executes a transaction on behalf of the account. - * This function is intended to be called by ERC-4337 EntryPoint.sol - * @dev Ensure adequate authorization control: i.e. onlyEntryPointOrSelf - * - * @dev MSA MUST implement this function signature. - * If a mode is requested that is not supported by the Account, it MUST revert - * @param mode The encoded execution mode of the transaction. See ModeLib.sol for details - * @param executionCalldata The encoded execution call data - */ - function execute(ModeCode mode, bytes calldata executionCalldata) external payable; - - /** - * @dev Executes a transaction on behalf of the account. - * This function is intended to be called by Executor Modules - * @dev Ensure adequate authorization control: i.e. onlyExecutorModule - * - * @dev MSA MUST implement this function signature. - * If a mode is requested that is not supported by the Account, it MUST revert - * @param mode The encoded execution mode of the transaction. See ModeLib.sol for details - * @param executionCalldata The encoded execution call data - */ - function executeFromExecutor( - ModeCode mode, - bytes calldata executionCalldata - ) external payable returns (bytes[] memory returnData); - - /** - * @dev ERC-1271 isValidSignature (included with openzeppelin) - * This function is intended to be used to validate a smart account signature - * and may forward the call to a validator module - * - * @param hash The hash of the data that is signed - * @param data The data that is signed - function isValidSignature( - bytes32 hash, - bytes calldata data - ) external view returns (bytes4); - */ - - /** - * @dev installs a Module of a certain type on the smart account - * @dev Implement Authorization control of your choosing - * @param moduleTypeId the module type ID according the ERC-7579 spec - * @param module the module address - * @param initData arbitrary data that may be required on the module during `onInstall` - * initialization. - */ - function installModule(uint256 moduleTypeId, address module, bytes calldata initData) external payable; - - /** - * @dev uninstalls a Module of a certain type on the smart account - * @dev Implement Authorization control of your cho0sing - * @param moduleTypeId the module type ID according the ERC-7579 spec - * @param module the module address - * @param deInitData arbitrary data that may be required on the module during `onUninstall` - * de-initialization. - */ - function uninstallModule(uint256 moduleTypeId, address module, bytes calldata deInitData) external payable; - - /** - * Function to check if the account supports a certain CallType or ExecType (see ModeLib.sol) - * @param encodedMode the encoded mode - */ - function supportsExecutionMode(ModeCode encodedMode) external view returns (bool); - - /** - * Function to check if the account supports installation of a certain module type Id - * @param moduleTypeId the module type ID according the ERC-7579 spec - */ - function supportsModule(uint256 moduleTypeId) external view returns (bool); - - /** - * Function to check if the account has a certain module installed - * @param moduleTypeId the module type ID according the ERC-7579 spec - * Note: keep in mind that some contracts can be multiple module types at the same time. It - * thus may be necessary to query multiple module types - * @param module the module address - * @param additionalContext additional context data that the smart account may interpret to - * identify conditions under which the module is installed. - * usually this is not necessary, but for some special hooks that - * are stored in mappings, this param might be needed - */ - function isModuleInstalled( - uint256 moduleTypeId, - address module, - bytes calldata additionalContext - ) external view returns (bool); - - /** - * @dev Returns the account id of the smart account - * @return accountImplementationId the account id of the smart account - * the accountId should be structured like so: - * "vendorname.accountname.semver" - */ - function accountId() external view returns (string memory accountImplementationId); -} diff --git a/packages/contracts/src/interfaces/IERC7579Validator.sol b/packages/contracts/src/interfaces/IERC7579Validator.sol deleted file mode 100644 index 8ae2a0e9..00000000 --- a/packages/contracts/src/interfaces/IERC7579Validator.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import { IERC7579Module } from "./IERC7579Module.sol"; -import { PackedUserOperation } from "./PackedUserOperation.sol"; - -interface IUserOpValidator is IERC7579Module { - error InvalidTargetAddress(address target); - - /** - * @dev Validates a transaction on behalf of the account. - * This function is intended to be called by the MSA during the ERC-4337 validation phase - * Note: solely relying on bytes32 hash and signature is not sufficient for some - * validation implementations (i.e. SessionKeys often need access to userOp.calldata) - * @param userOp The user operation to be validated. The userOp MUST NOT contain any metadata. - * The MSA MUST clean up the userOp before sending it to the validator. - * @param userOpHash The hash of the user operation to be validated - * @return return value according to ERC-4337 - */ - function validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external returns (uint256); - - /** - * Validator can be used for ERC-1271 validation - */ - function isValidSignatureWithSender(address sender, bytes32 hash, bytes calldata data) external view returns (bytes4); -} diff --git a/packages/contracts/src/interfaces/IClaveAccount.sol b/packages/contracts/src/interfaces/ISsoAccount.sol similarity index 90% rename from packages/contracts/src/interfaces/IClaveAccount.sol rename to packages/contracts/src/interfaces/ISsoAccount.sol index e5a4904f..774e0a6e 100644 --- a/packages/contracts/src/interfaces/IClaveAccount.sol +++ b/packages/contracts/src/interfaces/ISsoAccount.sol @@ -15,11 +15,11 @@ import { IUpgradeManager } from "./IUpgradeManager.sol"; import { IValidatorManager } from "./IValidatorManager.sol"; /** - * @title IClaveAccount - * @notice Interface for the Clave contract - * @dev Implementations of this interface are contract that can be used as a Clave + * @title ISsoAccount + * @notice Interface for the SSO contract + * @dev Implementations of this interface are contract that can be used as an SSO account (it's no longer Clave compatible) */ -interface IClaveAccount is +interface ISsoAccount is IERC1271Upgradeable, IERC721Receiver, IERC1155Receiver, diff --git a/packages/contracts/src/libraries/ERC7579Mode.sol b/packages/contracts/src/libraries/ERC7579Mode.sol index c06189fa..171c1d50 100644 --- a/packages/contracts/src/libraries/ERC7579Mode.sol +++ b/packages/contracts/src/libraries/ERC7579Mode.sol @@ -49,7 +49,6 @@ pragma solidity ^0.8.24; * ExecutionCallData: n bytes * single, delegatecall or batch exec abi.encoded as bytes */ -import { Execution } from "../interfaces/IERC7579Account.sol"; // Custom type for improved developer experience type ModeCode is bytes32; diff --git a/packages/contracts/src/libraries/Errors.sol b/packages/contracts/src/libraries/Errors.sol index 0f1c2bf1..e368e954 100644 --- a/packages/contracts/src/libraries/Errors.sol +++ b/packages/contracts/src/libraries/Errors.sol @@ -115,7 +115,7 @@ library Errors { error INVALID_MARKUP(); error USER_LIMIT_REACHED(); error INVALID_USER_LIMIT(); - error NOT_CLAVE_ACCOUNT(); + error NOT_SSO_ACCOUNT(); error EXCEEDS_MAX_SPONSORED_ETH(); /*////////////////////////////////////////////////////////////// diff --git a/packages/contracts/src/libraries/ClaveStorage.sol b/packages/contracts/src/libraries/SsoStorage.sol similarity index 89% rename from packages/contracts/src/libraries/ClaveStorage.sol rename to packages/contracts/src/libraries/SsoStorage.sol index 790b874b..f9ea5ae4 100644 --- a/packages/contracts/src/libraries/ClaveStorage.sol +++ b/packages/contracts/src/libraries/SsoStorage.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.24; -library ClaveStorage { +library SsoStorage { //keccak256('clave.contracts.ClaveStorage') - 1 - bytes32 private constant CLAVE_STORAGE_SLOT = 0x3248da1aeae8bd923cbf26901dc4bfc6bb48bb0fbc5b6102f1151fe7012884f4; + bytes32 private constant SSO_STORAGE_SLOT = 0x3248da1aeae8bd923cbf26901dc4bfc6bb48bb0fbc5b6102f1151fe7012884f4; struct Layout { // ┌───────────────────┐ @@ -24,7 +24,6 @@ library ClaveStorage { // │ Validation │ mapping(address => address) r1Validators; mapping(address => address) k1Validators; - mapping(address => address) userOpValidators; mapping(address => address) moduleValidators; uint256[50] __gap_2; // └───────────────────┘ @@ -46,7 +45,7 @@ library ClaveStorage { } function layout() internal pure returns (Layout storage l) { - bytes32 slot = CLAVE_STORAGE_SLOT; + bytes32 slot = SSO_STORAGE_SLOT; assembly { l.slot := slot } diff --git a/packages/contracts/src/managers/HookManager.sol b/packages/contracts/src/managers/HookManager.sol index 575e6c48..a187703a 100644 --- a/packages/contracts/src/managers/HookManager.sol +++ b/packages/contracts/src/managers/HookManager.sol @@ -6,7 +6,7 @@ import { Transaction } from "@matterlabs/zksync-contracts/l2/system-contracts/li import { ExcessivelySafeCall } from "@nomad-xyz/excessively-safe-call/src/ExcessivelySafeCall.sol"; import { Auth } from "../auth/Auth.sol"; -import { ClaveStorage } from "../libraries/ClaveStorage.sol"; +import { SsoStorage } from "../libraries/SsoStorage.sol"; import { AddressLinkedList } from "../libraries/LinkedList.sol"; import { Errors } from "../libraries/Errors.sol"; import { IExecutionHook, IValidationHook } from "../interfaces/IHook.sol"; @@ -245,15 +245,15 @@ abstract contract HookManager is IHookManager, Auth { } function _validationHooksLinkedList() private view returns (mapping(address => address) storage validationHooks) { - validationHooks = ClaveStorage.layout().validationHooks; + validationHooks = SsoStorage.layout().validationHooks; } function _executionHooksLinkedList() private view returns (mapping(address => address) storage executionHooks) { - executionHooks = ClaveStorage.layout().executionHooks; + executionHooks = SsoStorage.layout().executionHooks; } function _hookDataStore() private view returns (mapping(address => mapping(bytes32 => bytes)) storage hookDataStore) { - hookDataStore = ClaveStorage.layout().hookDataStore; + hookDataStore = SsoStorage.layout().hookDataStore; } function _supportsHook(address hook, bool isValidation) internal view returns (bool) { diff --git a/packages/contracts/src/managers/ModuleManager.sol b/packages/contracts/src/managers/ModuleManager.sol index b617338c..e27bb876 100644 --- a/packages/contracts/src/managers/ModuleManager.sol +++ b/packages/contracts/src/managers/ModuleManager.sol @@ -4,15 +4,14 @@ pragma solidity ^0.8.24; import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import { ExcessivelySafeCall } from "@nomad-xyz/excessively-safe-call/src/ExcessivelySafeCall.sol"; -import { ClaveStorage } from "../libraries/ClaveStorage.sol"; +import { SsoStorage } from "../libraries/SsoStorage.sol"; import { Auth } from "../auth/Auth.sol"; import { AddressLinkedList } from "../libraries/LinkedList.sol"; import { Errors } from "../libraries/Errors.sol"; import { IModule } from "../interfaces/IModule.sol"; import { IInitable } from "../interfaces/IInitable.sol"; -import { IClaveAccount } from "../interfaces/IClaveAccount.sol"; +import { ISsoAccount } from "../interfaces/ISsoAccount.sol"; import { IModuleManager } from "../interfaces/IModuleManager.sol"; -import { IUserOpValidator } from "../interfaces/IERC7579Validator.sol"; import { IERC7579Module, IExecutor } from "../interfaces/IERC7579Module.sol"; /** @@ -93,15 +92,6 @@ abstract contract ModuleManager is IModuleManager, Auth { emit AddModule(moduleAddress); } - function _addUserOpValidator(address module, bytes calldata data) internal virtual { - // Could do more validation on the validator (like does it exist already) - _userOpValidators().add(module); - - IUserOpValidator(module).onInstall(data); - - emit AddModule(module); - } - function _addExternalExecutorPermission(address module, bytes calldata data) internal virtual { _externalExecutorModule().add(module); @@ -111,7 +101,7 @@ abstract contract ModuleManager is IModuleManager, Auth { } function _addFallbackModule(address module, bytes calldata data) internal virtual { - ClaveStorage.layout().fallbackContractBySelector[bytes4(data[0:4])] = module; + SsoStorage.layout().fallbackContractBySelector[bytes4(data[0:4])] = module; IERC7579Module(module).onInstall(data); @@ -119,7 +109,7 @@ abstract contract ModuleManager is IModuleManager, Auth { } function _removeFallbackModule(address module, bytes calldata data) internal virtual { - ClaveStorage.layout().fallbackContractBySelector[bytes4(data[0:4])] = address(0); + SsoStorage.layout().fallbackContractBySelector[bytes4(data[0:4])] = address(0); IERC7579Module(module).onUninstall(data); @@ -140,23 +130,11 @@ abstract contract ModuleManager is IModuleManager, Auth { } function _modulesLinkedList() private view returns (mapping(address => address) storage modules) { - modules = ClaveStorage.layout().modules; - } - - function _userOpValidators() private view returns (mapping(address => address) storage modules) { - modules = ClaveStorage.layout().userOpValidators; - } - - function _uninstallValidator(address validator, bytes calldata data) internal { - _userOpValidators().remove(validator); - - IUserOpValidator(validator).onUninstall(data); - - emit RemoveModule(validator); + modules = SsoStorage.layout().modules; } function _externalExecutorModule() private view returns (mapping(address => address) storage modules) { - modules = ClaveStorage.layout().execModules; + modules = SsoStorage.layout().execModules; } function _removeExternalExecutorModule(address module, bytes calldata data) internal { diff --git a/packages/contracts/src/managers/OwnerManager.sol b/packages/contracts/src/managers/OwnerManager.sol index 1f05bf33..fa5a764c 100644 --- a/packages/contracts/src/managers/OwnerManager.sol +++ b/packages/contracts/src/managers/OwnerManager.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.24; -import { ClaveStorage } from "../libraries/ClaveStorage.sol"; +import { SsoStorage } from "../libraries/SsoStorage.sol"; import { BytesLinkedList, AddressLinkedList } from "../libraries/LinkedList.sol"; import { Errors } from "../libraries/Errors.sol"; import { Auth } from "../auth/Auth.sol"; -import { IClaveAccount } from "../interfaces/IClaveAccount.sol"; +import { ISsoAccount } from "../interfaces/ISsoAccount.sol"; import { IOwnerManager } from "../interfaces/IOwnerManager.sol"; /** @@ -113,11 +113,11 @@ abstract contract OwnerManager is IOwnerManager, Auth { } function _r1OwnersLinkedList() internal view returns (mapping(bytes => bytes) storage r1Owners) { - r1Owners = ClaveStorage.layout().r1Owners; + r1Owners = SsoStorage.layout().r1Owners; } function _k1OwnersLinkedList() internal view returns (mapping(address => address) storage k1Owners) { - k1Owners = ClaveStorage.layout().k1Owners; + k1Owners = SsoStorage.layout().k1Owners; } function _r1ClearOwners() private { diff --git a/packages/contracts/src/managers/ValidatorManager.sol b/packages/contracts/src/managers/ValidatorManager.sol index 16fb1b4d..94c8f540 100644 --- a/packages/contracts/src/managers/ValidatorManager.sol +++ b/packages/contracts/src/managers/ValidatorManager.sol @@ -5,7 +5,7 @@ import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC16 import { Auth } from "../auth/Auth.sol"; import { Errors } from "../libraries/Errors.sol"; -import { ClaveStorage } from "../libraries/ClaveStorage.sol"; +import { SsoStorage } from "../libraries/SsoStorage.sol"; import { AddressLinkedList } from "../libraries/LinkedList.sol"; import { IR1Validator, IK1Validator } from "../interfaces/IValidator.sol"; import { IValidatorManager } from "../interfaces/IValidatorManager.sol"; @@ -160,14 +160,14 @@ abstract contract ValidatorManager is IValidatorManager, Auth { } function _r1ValidatorsLinkedList() private view returns (mapping(address => address) storage r1Validators) { - r1Validators = ClaveStorage.layout().r1Validators; + r1Validators = SsoStorage.layout().r1Validators; } function _moduleValidatorsLinkedList() private view returns (mapping(address => address) storage moduleValidators) { - moduleValidators = ClaveStorage.layout().moduleValidators; + moduleValidators = SsoStorage.layout().moduleValidators; } function _k1ValidatorsLinkedList() private view returns (mapping(address => address) storage k1Validators) { - k1Validators = ClaveStorage.layout().k1Validators; + k1Validators = SsoStorage.layout().k1Validators; } } diff --git a/packages/contracts/src/test/ExampleAuthServerPaymaster.sol b/packages/contracts/src/test/ExampleAuthServerPaymaster.sol index 3495df79..6037b7a1 100644 --- a/packages/contracts/src/test/ExampleAuthServerPaymaster.sol +++ b/packages/contracts/src/test/ExampleAuthServerPaymaster.sol @@ -16,7 +16,7 @@ import { SessionKeyValidator } from "../validators/SessionKeyValidator.sol"; contract ExampleAuthServerPaymaster is IPaymaster, Ownable { address public immutable AA_FACTORY_CONTRACT_ADDRESS; address public immutable SESSION_KEY_VALIDATOR_CONTRACT_ADDRESS; - bytes4 constant DEPLOY_ACCOUNT_SELECTOR = AAFactory.deployProxy7579Account.selector; + bytes4 constant DEPLOY_ACCOUNT_SELECTOR = AAFactory.deployProxySsoAccount.selector; bytes4 constant CREATE_SESSION_SELECTOR = SessionKeyValidator.createSession.selector; modifier onlyBootloader() { @@ -46,7 +46,7 @@ contract ExampleAuthServerPaymaster is IPaymaster, Ownable { "Unsupported contract address" ); - // Ensure the transaction is calling either the deployProxy7579Account or createSession functions + // Ensure the transaction is calling either the deployProxySsoAccount or createSession functions require(_transaction.data.length >= 4, "Transaction data is too short"); bytes4 methodSelector = bytes4(_transaction.data[0:4]); if (to == AA_FACTORY_CONTRACT_ADDRESS) { diff --git a/packages/contracts/test/BasicTest.ts b/packages/contracts/test/BasicTest.ts index 7488c7a7..f93672fe 100644 --- a/packages/contracts/test/BasicTest.ts +++ b/packages/contracts/test/BasicTest.ts @@ -4,7 +4,7 @@ import { Wallet, ZeroAddress } from "ethers"; import { it } from "mocha"; import { SmartAccount, utils } from "zksync-ethers"; -import { ERC7579Account__factory } from "../typechain-types"; +import { SsoAccount__factory } from "../typechain-types"; import { CallStruct } from "../typechain-types/src/batch/BatchCaller"; import { ContractFixtures, getProvider } from "./utils"; @@ -36,7 +36,7 @@ describe("Basic tests", function () { const aaFactoryContract = await fixtures.getAaFactory(); assert(aaFactoryContract != null, "No AA Factory deployed"); - const deployTx = await aaFactoryContract.deployProxy7579Account( + const deployTx = await aaFactoryContract.deployProxySsoAccount( randomBytes(32), "id", [], @@ -48,7 +48,7 @@ describe("Basic tests", function () { expect(proxyAccountAddress, "the proxy account location via logs").to.not.equal(ZeroAddress, "be a valid address"); - const account = ERC7579Account__factory.connect(proxyAccountAddress, provider); + const account = SsoAccount__factory.connect(proxyAccountAddress, provider); assert(await account.k1IsOwner(fixtures.wallet.address)); }); @@ -109,7 +109,7 @@ describe("Basic tests", function () { }, ]; - const account = ERC7579Account__factory.connect(proxyAccountAddress, provider); + const account = SsoAccount__factory.connect(proxyAccountAddress, provider); const aaTx = { ...await aaTxTemplate(), diff --git a/packages/contracts/test/SessionKeyTest.ts b/packages/contracts/test/SessionKeyTest.ts index e03bc5fa..770b5645 100644 --- a/packages/contracts/test/SessionKeyTest.ts +++ b/packages/contracts/test/SessionKeyTest.ts @@ -6,7 +6,7 @@ import { it } from "mocha"; import { SmartAccount, utils } from "zksync-ethers"; import type { ERC20 } from "../typechain-types"; -import { AAFactory__factory, ERC7579Account__factory } from "../typechain-types"; +import { AAFactory__factory, SsoAccount__factory } from "../typechain-types"; import type { AAFactory } from "../typechain-types/src/AAFactory"; import type { SessionLib } from "../typechain-types/src/validators/SessionKeyValidator"; import { ContractFixtures, getProvider, logInfo } from "./utils"; @@ -250,8 +250,8 @@ describe("SessionKeyModule tests", function () { assert(verifierContract != null, "No verifier deployed"); const sessionModuleContract = await fixtures.getSessionKeyContract(); assert(sessionModuleContract != null, "No session module deployed"); - const erc7579Contract = await fixtures.getAccountImplContract(); - assert(erc7579Contract != null, "No ERC7579 deployed"); + const ssoContract = await fixtures.getAccountImplContract(); + assert(ssoContract != null, "No SSO Account deployed"); const factoryContract = await fixtures.getAaFactory(); assert(factoryContract != null, "No AA Factory deployed"); const authServerPaymaster = await fixtures.deployExampleAuthServerPaymaster( @@ -263,7 +263,7 @@ describe("SessionKeyModule tests", function () { logInfo(`Session Address : ${await sessionModuleContract.getAddress()}`); logInfo(`Passkey Address : ${await verifierContract.getAddress()}`); logInfo(`Account Factory Address : ${await factoryContract.getAddress()}`); - // logInfo(`Account Implementation Address : ${await erc7579Contract.getAddress()}`); + // logInfo(`Account Implementation Address : ${await ssoContract.getAddress()}`); logInfo(`Auth Server Paymaster Address : ${await authServerPaymaster.getAddress()}`); }); @@ -272,7 +272,7 @@ describe("SessionKeyModule tests", function () { const sessionKeyModuleAddress = await fixtures.getSessionKeyModuleAddress(); const sessionKeyPayload = abiCoder.encode(["address", "bytes"], [sessionKeyModuleAddress, "0x"]); - const deployTx = await factoryContract.deployProxy7579Account( + const deployTx = await factoryContract.deployProxySsoAccount( randomBytes(32), "id", [], @@ -287,7 +287,7 @@ describe("SessionKeyModule tests", function () { const fundTx = await fixtures.wallet.sendTransaction({ value: parseEther("1"), to: proxyAccountAddress }); await fundTx.wait(); - const account = ERC7579Account__factory.connect(proxyAccountAddress, provider); + const account = SsoAccount__factory.connect(proxyAccountAddress, provider); assert(await account.k1IsOwner(fixtures.wallet.address)); assert(await account.isHook(sessionKeyModuleAddress), "session key module should be a hook"); assert(await account.isModuleValidator(sessionKeyModuleAddress), "session key module should be a validator"); diff --git a/packages/contracts/test/utils.ts b/packages/contracts/test/utils.ts index 93cb1606..e1994bca 100644 --- a/packages/contracts/test/utils.ts +++ b/packages/contracts/test/utils.ts @@ -9,8 +9,8 @@ import * as hre from "hardhat"; import { ContractFactory, Provider, utils, Wallet } from "zksync-ethers"; import { base64UrlToUint8Array, getPublicKeyBytesFromPasskeySignature, unwrapEC2Signature } from "zksync-sso/utils"; -import { AAFactory, ERC20, ERC7579Account, ExampleAuthServerPaymaster, SessionKeyValidator, WebAuthValidator } from "../typechain-types"; -import { AAFactory__factory, ERC20__factory, ERC7579Account__factory, ExampleAuthServerPaymaster__factory, SessionKeyValidator__factory, WebAuthValidator__factory } from "../typechain-types"; +import { AAFactory, ERC20, ExampleAuthServerPaymaster, SessionKeyValidator, SsoAccount, WebAuthValidator } from "../typechain-types"; +import { AAFactory__factory, ERC20__factory, ExampleAuthServerPaymaster__factory, SessionKeyValidator__factory, SsoAccount__factory, WebAuthValidator__factory } from "../typechain-types"; export class ContractFixtures { readonly wallet: Wallet = getWallet(LOCAL_RICH_WALLETS[0].privateKey); @@ -67,12 +67,11 @@ export class ContractFixtures { return this._passkeyModuleAddress; } - private _accountImplContract: ERC7579Account; - // wraps the clave account + private _accountImplContract: SsoAccount; async getAccountImplContract() { if (!this._accountImplContract) { - const contract = await create2("ERC7579Account", this.wallet, this.ethersStaticSalt); - this._accountImplContract = ERC7579Account__factory.connect(await contract.getAddress(), this.wallet); + const contract = await create2("SsoAccount", this.wallet, this.ethersStaticSalt); + this._accountImplContract = SsoAccount__factory.connect(await contract.getAddress(), this.wallet); } return this._accountImplContract; } diff --git a/packages/sdk/src/abi/Factory.ts b/packages/sdk/src/abi/Factory.ts index c941ee42..292dd32e 100644 --- a/packages/sdk/src/abi/Factory.ts +++ b/packages/sdk/src/abi/Factory.ts @@ -120,7 +120,7 @@ export const FactoryAbi = [ type: "address[]", }, ], - name: "deployProxy7579Account", + name: "deployProxySsoAccount", outputs: [ { internalType: "address", diff --git a/packages/sdk/src/client/actions/account.ts b/packages/sdk/src/client/actions/account.ts index e1e6cbdb..7ce80977 100644 --- a/packages/sdk/src/client/actions/account.ts +++ b/packages/sdk/src/client/actions/account.ts @@ -88,7 +88,7 @@ export const deployAccount = async < chain: client.chain!, address: args.contracts.accountFactory, abi: FactoryAbi, - functionName: "deployProxy7579Account", + functionName: "deployProxySsoAccount", args: [ toHex(args.salt), accountId,