## Background
Sometimes, you don't want a transaction to be sent right away. For example, there might be an NFT mint that starts tomorrow at 7AM, but you don't want to wake up at 7AM to mint the NFT. With fun.xyz's automated actions, you can schedule a transaction at 7AM, pre-sign it, and make sure it only executes when the NFT mint opens.
This document explains the design decisions and the architecture of Automated Actions. This includes smart contract design, sdk changes, server changes, storage changes(dynamoDB), and a new service that simulates transactions and sends them to bundler.
## Tenets
Availability: When an automated action is scheduled, it should be executed as soon as the validation condition is true
Scalability: We want to minimize the costs are are paying to aws, dynamoDB, our api server, and the cost of rpcs for simulation
## Customer Experience
### Creating an Automated Action
Each automated action is based off of a module, which is a smart contract that plugs into funwallet.sol. Each automated action module has two functions `validate(bytes calldata data)` and `execute(bytes calldata data)`
```
contract AutomatedAction {
function validate(bytes calldata data) public returns(bool){
}
function execute(bytes calldata data) external {}
}
```
The validate function will repeatedly be called, and the execute will be called as soon as validate returns true for that specific `data`.
### Sending an Automated Action
Automated Actions are sent from the SDK. When sending a transaction, a user can specify `automatedAction=true` in {Insert correct function from sdk here} and the transaction will be sent to the automated actions database instead of to the bundler
### The Automated Action being executed
The automated action userOp will sit in the database and the corresponding `validate()` function will be called. When validate returns true, the userOp will be sent to the bundler.
## Architecture

## Api Server Changes
### /createAutomatedAction
Parameters:
- chainId: number
- actionType: ActionType
- userOp: UserOperation
- moduleAddress: string
- data: BytesLike
- walletAddress: string
Creates an entry in the FunWalletAction DynamoDB
- status: Enum {Pending, Cancelled, Success, Failed}
returns actionId
### /deleteAutomatedAction
- actionId: string
- chainId: string
Deletes an entry in the FunWalletAction DynamoDB
We could also just use the existing delete method
### /executeAutomatedAction
- actionId: string
- chainId: string
- entryPointAddress: string
## Database Schema
We are using the same database `FunWalletAction` as the one being used in M of N transactions.
```
@table(FUN_WALLET_ACTION_TABLE_NAME)
export class FunWalletAction {
@hashKey()
actionId: string
@rangeKey()
chainId: string
@versionAttribute()
version: number
@attribute()
actionType: ActionType
@attribute()
authType: AuthType
@attribute()
groupId: string
@attribute()
message: string
@attribute()
walletAddr: string
@attribute()
nonce: string
@attribute()
userOp: UserOperation
@attribute()
status: FunWalletActionStatus
@attribute()
proposer: string
@attribute()
proposedTime: number
@attribute()
executedBy: string
@attribute()
executedTime: number
@attribute()
relatedActionIds: string[]
@attribute()
signatures: Signature[]
@attribute()
lastUpdatedTime: number
## These are new fields
@attribute()
data: string
@attribute()
moduleAddress: string
}
```
Might need to add a some key that lets us only query the actions that are relevant to automatedActions
## Cron Job
Tbh not sure what aws service to use here, but essentially we would:
1. Fetch all Actions from dynamoDB
2. For each action, check moduleAddress.validate(data) which is an onchain call. If this returns true, then send the userOp to the bundler. If this returns false, do nothing
## SDK
First class action vs sendTxLater
## Implementation Plan
- Write Demo smart contracts for automated actions(done)
- Create api server changes
- Create SDK changes
- Create Cron Job server
Do we every verify nonces in useroperations? If so, do we just check that the nonce has not been used in the past? If we check that the nonce > previous nonce + 1, automated actions will only be able to work in the order that you create automated actions in. If not, this might be a security issue, but not for automated actions
Is the dynamoDB live?
What do we use sendTxLater for? if that is true, can we just send the automated action to the database?