-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ported over all module examples and tests
- Loading branch information
Showing
26 changed files
with
4,292 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/bin/bash | ||
|
||
# Check if directory path is provided | ||
if [ -z "$1" ]; then | ||
echo "Usage: ./create_project.sh <directory_path>" | ||
exit 1 | ||
fi | ||
|
||
# Create the directory if it doesn't exist | ||
mkdir -p $1 | ||
|
||
# Navigate to the directory | ||
cd $1 | ||
|
||
# Download package.json using wget from a fixed URL | ||
wget -O package.json <fixed_URL_placeholder> | ||
|
||
# Create src and test folders | ||
mkdir src test | ||
|
||
# Write "modulekit/=../." into remappings.txt | ||
echo "modulekit/=../." > remappings.txt | ||
|
||
echo "Project scaffolding created successfully." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.23; | ||
|
||
import "@rhinestone/sessionkeymanager/src/ISessionValidationModule.sol"; | ||
import { IERC20 } from "forge-std/interfaces/IERC20.sol"; | ||
import { IERC7579Account } from "@rhinestone/modulekit/src/Accounts.sol"; | ||
import { ERC7579ExecutorBase } from "@rhinestone/modulekit/src/Modules.sol"; | ||
import { ModeLib } from "erc7579/lib/ModeLib.sol"; | ||
import { ExecutionLib } from "erc7579/lib/ExecutionLib.sol"; | ||
import { EncodedModuleTypes, ModuleTypeLib, ModuleType } from "erc7579/lib/ModuleTypeLib.sol"; | ||
|
||
contract AutoSendSessionKey is ERC7579ExecutorBase, ISessionValidationModule { | ||
struct ExecutorAccess { | ||
address sessionKeySigner; | ||
address token; | ||
address receiver; | ||
} | ||
|
||
struct SpentLog { | ||
uint128 spent; | ||
uint128 maxAmount; | ||
} | ||
|
||
struct Params { | ||
address token; | ||
address receiver; | ||
uint128 amount; | ||
} | ||
|
||
error InvalidMethod(bytes4); | ||
error InvalidValue(); | ||
error InvalidAmount(); | ||
error InvalidTarget(); | ||
error InvalidRecipient(); | ||
|
||
mapping(address account => mapping(address token => SpentLog)) internal _log; | ||
|
||
function encode(ExecutorAccess memory transaction) public pure returns (bytes memory) { | ||
return abi.encode(transaction); | ||
} | ||
|
||
function getSpentLog(address account, address token) public view returns (SpentLog memory) { | ||
return _log[account][token]; | ||
} | ||
|
||
function autoSend(Params calldata params) external { | ||
IERC7579Account smartAccount = IERC7579Account(msg.sender); | ||
|
||
SpentLog storage log = _log[msg.sender][params.token]; | ||
|
||
uint128 newSpent = log.spent + params.amount; | ||
if (newSpent > log.maxAmount) { | ||
revert InvalidAmount(); | ||
} | ||
log.spent = newSpent; | ||
|
||
smartAccount.executeFromExecutor( | ||
ModeLib.encodeSimpleSingle(), | ||
ExecutionLib.encodeSingle( | ||
params.token, 0, abi.encodeCall(IERC20.transfer, (params.receiver, params.amount)) | ||
) | ||
); | ||
} | ||
|
||
function validateSessionParams( | ||
address destinationContract, | ||
uint256 callValue, | ||
bytes calldata callData, | ||
bytes calldata _sessionKeyData, | ||
bytes calldata /*_callSpecificData*/ | ||
) | ||
public | ||
virtual | ||
override | ||
returns (address) | ||
{ | ||
ExecutorAccess memory access = abi.decode(_sessionKeyData, (ExecutorAccess)); | ||
|
||
bytes4 targetSelector = bytes4(callData[:4]); | ||
Params memory params = abi.decode(callData[4:], (Params)); | ||
if (targetSelector != this.autoSend.selector) { | ||
revert InvalidMethod(targetSelector); | ||
} | ||
|
||
if (params.receiver != access.receiver) { | ||
revert InvalidRecipient(); | ||
} | ||
|
||
if (destinationContract != address(this)) { | ||
revert InvalidTarget(); | ||
} | ||
|
||
if (params.token != access.token) { | ||
revert InvalidTarget(); | ||
} | ||
|
||
if (callValue != 0) { | ||
revert InvalidValue(); | ||
} | ||
|
||
return access.sessionKeySigner; | ||
} | ||
|
||
function onInstall(bytes calldata data) external override { | ||
(address[] memory tokens, SpentLog[] memory log) = abi.decode(data, (address[], SpentLog[])); | ||
|
||
for (uint256 i; i < tokens.length; i++) { | ||
_log[msg.sender][tokens[i]] = log[i]; | ||
} | ||
} | ||
|
||
function onUninstall(bytes calldata data) external override { } | ||
|
||
function isModuleType(uint256 typeID) external pure override returns (bool) { | ||
return typeID == TYPE_EXECUTOR; | ||
} | ||
|
||
function getModuleTypes() external view returns (EncodedModuleTypes) { } | ||
|
||
function isInitialized(address smartAccount) external view returns (bool) { } | ||
|
||
function name() external pure virtual returns (string memory) { | ||
return "AutoSend"; | ||
} | ||
|
||
function version() external pure virtual returns (string memory) { | ||
return "0.0.1"; | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
examples/src/ColdStorage-SubAccount/ColdStorageExecutor.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.23; | ||
|
||
import { IERC7579Account } from "@rhinestone/modulekit/src/Accounts.sol"; | ||
import { ERC7579ExecutorBase } from "@rhinestone/modulekit/src/Modules.sol"; | ||
import { ModeLib } from "erc7579/lib/ModeLib.sol"; | ||
import { ExecutionLib } from "erc7579/lib/ExecutionLib.sol"; | ||
import { EncodedModuleTypes, ModuleTypeLib, ModuleType } from "erc7579/lib/ModuleTypeLib.sol"; | ||
|
||
contract ColdStorageExecutor is ERC7579ExecutorBase { | ||
error UnauthorizedAccess(); | ||
|
||
mapping(address subAccount => address owner) private _subAccountOwner; | ||
|
||
function executeOnSubAccount(address subAccount, bytes calldata callData) external payable { | ||
if (msg.sender != _subAccountOwner[subAccount]) { | ||
revert UnauthorizedAccess(); | ||
} | ||
|
||
IERC7579Account(subAccount).executeFromExecutor(ModeLib.encodeSimpleSingle(), callData); | ||
} | ||
|
||
function onInstall(bytes calldata data) external override { | ||
address owner = address(bytes20(data[0:20])); | ||
_subAccountOwner[msg.sender] = owner; | ||
} | ||
|
||
function onUninstall(bytes calldata) external override { | ||
delete _subAccountOwner[msg.sender]; | ||
} | ||
|
||
function isModuleType(uint256 typeID) external pure override returns (bool) { | ||
return typeID == TYPE_EXECUTOR; | ||
} | ||
|
||
function getModuleTypes() external view returns (EncodedModuleTypes) { } | ||
|
||
function isInitialized(address smartAccount) external view returns (bool) { | ||
return _subAccountOwner[smartAccount] != address(0); | ||
} | ||
} |
Oops, something went wrong.