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.
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
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
.
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 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.
Parameters:
Creates an entry in the FunWalletAction DynamoDB
Deletes an entry in the FunWalletAction DynamoDB
We could also just use the existing delete method
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
Tbh not sure what aws service to use here, but essentially we would:
First class action vs sendTxLater
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?