Welcome to the first of our weekly updates on the progress of MynaWallet! This report serves as an update on the grant received from the Ethereum Foundation. This is an exciting journey that we’ve embarked upon, and we want to make sure everyone— from our team to our supporters and interested developers— is kept in the loop about what we’re working on.

Our milestones for the first week have been:

Our outcomes are:

Let’s deep dive into each topic.

The draft of the contract wallet architecture and functionalities

This week, we utilized the base contract released by eth-infinitism to create the foundational aspects of a contract that allows wallet operations through RSA signature verification.

During the initialization of the wallet, a portion of the RSA public key (specifically, the modulus) that holds the operational authority for that wallet is registered in the contract. The validateSignature function is modified to verify RSA signatures in PKCSv1.5 format. Operations are permitted only if the signature can be verified with the registered modulus. For RSA signature verification on-chain, we leveraged a library developed by adria0.

Key Takeaways of MynaWallet-Related Contracts

We’ll highlight some of the key features and takeaways related to the contracts within the MynaWallet and MynaWallet Factory. While we aim to provide key points here, we highly recommend that for a more granular understanding, you consult the actual codebase on our GitHub repository.

`// SPDX-License-Identifier: GPL-3.0 pragma solidity **^**0.8.19; ....

contract MynaWallet isBaseAccount, Auth, EntryPointManager, OwnerManager, EIP1271Manager, TokenCallbackHandler, UUPSUpgradeable, Initializable { /* * @dev The _entryPoint member is immutable, to reduce gas consumption. * the implementation by calling upgradeTo() * @param newModulus modulus of the RSA public key which can operate this contract */*function initialize(bytes memory newModulus) external initializer { _setOwner(newModulus); emit MynaWalletInitialized(entryPoint(), newModulus); }

*/**
* @notice Validate UserOperation and its signature, currently only supports RSA signature
* @dev Internal function
* @param userOp user operation
* @param userOpHash hash of the user operation
* @return validationData 0 if valid
*/***function** _validateSignature(UserOperation **calldata** userOp, **bytes32** userOpHash)
    **internaloverridereturns** (**uint256** validationData)
{
    **bytes32** hashed **=** sha256(abi.encode(userOpHash));
    (**bytes** **memory** modulus, **bytes** **memory** exponent) **=** getOwner();
    **uint256** ret **=** verifyPkcs1Sha256(hashed, userOp.signature, exponent, modulus);
    **if** (ret **!=** 0) **return** SIG_VALIDATION_FAILED;
} 
...

}`

initialize(**bytes** **memory** newModulus) **external** initializer

During the initial verification phase of the first UserOperation, if the user’s proxy has not been deployed yet, it will be deployed and initialized with the user’s modulus.

_validateSignature(UserOperation **calldata** userOp, **bytes32** userOpHash) **internal** **override** **returns** (**uint256** validationData)

In order to execute UserOperation, we validate signatures by referencing the saved modulus and a constant exponent during the validation phase. If the signature is verified, the EntryPoint contract proceeds to execute the UserOperation in the subsequent execution phase.

Because our contracts are based on eth-infinitism, each user’s account is a proxy that references the implementation contract and our factory contract deploys each user’s proxy.