Skip to content

Commit

Permalink
support trigge, node and edges
Browse files Browse the repository at this point in the history
  • Loading branch information
v9n committed Nov 13, 2024
1 parent c3dcb7f commit 97678d1
Show file tree
Hide file tree
Showing 11 changed files with 2,551 additions and 1,459 deletions.
1 change: 1 addition & 0 deletions aggregator/repl.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func (agg *Aggregator) stopRepl() {
func (agg *Aggregator) startRepl() {
var err error
repListener, err = net.Listen("unix", agg.config.SocketPath)

if err != nil {
return
}
Expand Down
6 changes: 2 additions & 4 deletions core/taskengine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func (n *Engine) CreateTask(user *model.User, taskPayload *avsproto.CreateTaskRe
task, err := model.NewTaskFromProtobuf(user, taskPayload)

if err != nil {
return nil, err
return nil, status.Errorf(codes.Code(avsproto.Error_TaskDataMissingError), err.Error())
}

updates := map[string][]byte{}
Expand Down Expand Up @@ -395,9 +395,7 @@ func (n *Engine) ListTasksByUser(user *model.User, payload *avsproto.ListTasksRe
func (n *Engine) GetTaskByID(taskID string) (*model.Task, error) {
for status, _ := range avsproto.TaskStatus_name {
if rawTaskData, err := n.db.GetKey(TaskStorageKey(taskID, avsproto.TaskStatus(status))); err == nil {
task := &model.Task{
ID: taskID,
}
task := model.NewTask()
err = task.FromStorageData(rawTaskData)

if err == nil {
Expand Down
7 changes: 4 additions & 3 deletions core/taskengine/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,18 @@ func (c *ContractProcessor) Perform(job *apqueue.Job) error {
// Process entrypoint node, then from the next pointer, and flow of the node, we will follow the chain of execution
action := task.Nodes[0]

if action.GetContractExecution() == nil {
// TODO: move to vm.go
if action.GetContractWrite() == nil {
err := fmt.Errorf("invalid task action")
task.AppendExecution(currentTime.Unix(), "", err)
task.SetFailed()
return err
}

userOpCalldata, e := aa.PackExecute(
common.HexToAddress(action.GetContractExecution().ContractAddress),
common.HexToAddress(action.GetContractWrite().ContractAddress),
big.NewInt(0),
common.FromHex(action.GetContractExecution().CallData),
common.FromHex(action.GetContractWrite().CallData),
)
//calldata := common.FromHex("b61d27f600000000000000000000000069256ca54e6296e460dec7b29b7dcd97b81a3d55000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000e0f7d11fd714674722d325cd86062a5f1882e13a0000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000")

Expand Down
39 changes: 36 additions & 3 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,37 @@
# Ava Protocol Example
# Ava Protocol Examples

Example code on how to interact with Ava Protocol RPC server to create and
manage task.
Example codes on how to interact with Ava Protocol RPC server to create and
manage tasks.

Examples weren't written to be parameterized or extensible. Its only purpose
is to show how to run a specific example, and allow the audience to see
how the code will look like.

Therefore, the script is harded coded, there is no parameter to provide or anything.

If you need to change a parameter for a test, edit the code and re-run it.

# Available example

## Prepare depedencies

```
npm ci
```

Then run:

```
node example.js
```

it will list all available action to run.

## Setting env

```
export env=<development|staging|production>
export PRIVATE_KEY=<any-wallet-private-key>
```

The test example using a dummy token which anyone can mint https://sepolia.etherscan.io/address/0x2e8bdb63d09ef989a0018eeb1c47ef84e3e61f7b#writeProxyContract
83 changes: 54 additions & 29 deletions examples/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ async function listTask(owner, token) {
smart_wallet_address: process.argv[3]
}, metadata);

console.log("Tasks that has created by", process.argv[3], result);
console.log(`Found ${result.tasks.length} tasks created by`, process.argv[3]);

for (const item of result.tasks) {
console.log("task", item.id, "data", item,"\n=================================\n");
console.log("\n\ntask id:", item.id, "taskdata", item,"\n=================================\n");
}
}

Expand Down Expand Up @@ -240,9 +240,11 @@ const main = async (cmd) => {
case "create-wallet":
salt = process.argv[3] || 0;
let smartWalletAddress = await createWallet(owner, token, process.argv[3], process.argv[4]);
console.log("inside vm", smartWalletAddress)
console.log("generated smart wallet", smartWalletAddress)
break;
case "schedule":
case "schedule-cron":
case "schedule-event":
// ETH-USD pair on sepolia
// https://sepolia.etherscan.io/address/0x694AA1769357215DE4FAC081bf1f309aDC325306#code
// The price return is big.Int so we have to use the cmp function to compare
Expand Down Expand Up @@ -315,12 +317,13 @@ const main = async (cmd) => {
default:
console.log(`Usage:
create-wallet <salt> <factory-address>: to create a smart wallet with a salt, and optionally a factory contract
wallet: to find smart wallet address for this eoa
tasks: to find all tasks
get <task-id>: to get task detail
schedule: to schedule a task with chainlink eth-usd its condition will be matched quickly
schedule2: to schedule a task with chainlink that has a very high price target
create-wallet <salt> <factory-address(optional)>: to create a smart wallet with a salt, and optionally a factory contract
wallet: to list smart wallet address that has been created. note that a default wallet with salt=0 will automatically created
tasks <smart-wallet-address>: to list all tasks of given smart wallet address
get <task-id>: to get task detail. a permission error is throw if the eoa isn't the smart wallet owner.
schedule <smart-wallet-address>: to schedule a task that run on every block, with chainlink eth-usd its condition will be matched quickly
schedule-cron <smart-wallet-address>: to schedule a task that run on cron
schedule-event <smart-wallet-address>: to schedule a task that run on occurenct of an event
schedule-generic: to schedule a task with an arbitrary contract query
cancel <task-id>: to cancel a task
delete <task-id>: to completely remove a task`);
Expand All @@ -346,6 +349,12 @@ async function scheduleERC20TransferJob(owner, token, taskCondition) {
// Now we can schedule a task
// 1. Generate the calldata to check condition
const taskBody = getTaskData();
const smartWalletAddress = process.argv[3];
if (!smartWalletAddress) {
console.log("invalid smart wallet address. check usage");
return
}

console.log("\n\nTask body:", taskBody);

console.log("\n\nTask condition:", taskCondition);
Expand All @@ -356,13 +365,13 @@ async function scheduleERC20TransferJob(owner, token, taskCondition) {
console.log("Trigger type", TriggerType.EXPRESSIONTRIGGER);

let trigger = {
trigger_type: TriggerType.EVENTTRIGGER,
event: {
expression: taskCondition,
}
};

if (process.argv[2] == "time") {
trigger_type: TriggerType.BLOCKTRIGGER,
block: {
interval: 5, // run every 5 block
},
};
if (process.argv[2] == "schedule-cron") {
trigger = {
trigger_type: TriggerType.TIMETRIGGER,
cron: {
Expand All @@ -372,34 +381,50 @@ async function scheduleERC20TransferJob(owner, token, taskCondition) {
],
},
}
} else if (process.argv[3] == "block") {
} else if (process.argv[2] == "schedule-event") {
trigger = {
trigger_type: TriggerType.BLOCKTRIGGER,
block: {
interval: 5, // run every 5 block
},
trigger_type: TriggerType.EVENTTRIGGER,
event: {
expression: taskCondition,
}
}
}

const result = await asyncRPC(
client,
'CreateTask',
{
// salt = 0
//smart_wallet_address: "0x5Df343de7d99fd64b2479189692C1dAb8f46184a",
smart_wallet_address: "0xdD85693fd14b522a819CC669D6bA388B4FCd158d",
actions: [{
task_type: TaskType.CONTRACTEXECUTIONTASK,
// id need to be unique
smart_wallet_address: smartWalletAddress,
nodes: [{
task_type: TaskType.FILERTASK,
id: 'get_oracle_price',
branch: {
"if": {
expression: `bigCmp(priceChainlink("${config[env].ORACLE_PRICE_CONTRACT}"),toBigInt("10000") > 0`,
next: 'transfer_erc20_1'
}
}

}, {
task_type: TaskType.CONTRACTWRITETASK,
// id need to be unique. it will be assign to the variable
id: 'transfer_erc20_1',
// name is for our note only
// name is for our note only. use for display a humand friendly version
name: 'Transfer Test Token',
contract_execution: {
contract_write: {
// Our ERC20 test token
contract_address: config[env].TEST_TRANSFER_TOKEN,
call_data: taskBody,
}
}],

edges: [{
id: 'edge-123abcdef',
// entrypoint
start: 'transfer_erc20_1',
// there is no end needed on this task
}],

trigger,
start_at: Math.floor(Date.now() / 1000) + 30,
expired_at: Math.floor(Date.now() / 1000 + 3600 * 24 * 30),
Expand Down
Loading

0 comments on commit 97678d1

Please sign in to comment.