Skip to content
Trevor Clarke edited this page May 2, 2022 · 2 revisions

Reference: Commands

For a list of up-to-date commands, run croncat --help in your terminal.

Usage: croncat <command> [options]

  

Commands:

croncat register <account_id> [payable_account_id] Add your agent to cron known agents

croncat update <account_id> [payable_account_id] Update your agent to cron known agents

croncat unregister <account_id> Account to remove from list of active agents.

croncat withdraw [account_id] Withdraw all rewards earned for this account

croncat status [account_id] Check agent status and balance for this account

croncat tasks Check tasks list

croncat go [account_id] Run tasks that are available, if agent is registered and has balance

croncat daemon [near_env] Generate a network specific croncat daemon service

NOTE: I have removed "triggers" for now, as they do not make sense. The task loop will change slightly to handle the old model of triggers.

Croncat CLI Install:

Install should cover downloading, creating local signing keys, and setting up a system daemon for the user. The user should be able to get started as an agent as soon as they have funded the newly generated keys.


Croncat CLI Flows:

This is broken into 2 camps, to make things more straight forward to understand.


1. Quick Data Checks

Check Agent Status

# Check agent status and balance for this account (Optional: account_id)

croncat status [account_id]

This uses QueryMsg::GetAgent { account_id: Addr } query, returning the data in a human readable format from the json response. The response will be type Agent.

Check Tasks

# Check tasks total for this agent.

croncat tasks

This uses QueryMsg::GetAgentTasks { account_id: Addr } query, returning the simple amount of tasks that are available to this agent. The response will be type GetAgentTasksResponse(u64, u128).

Check Croncat Info

# Check information and config for the croncat runtime on chain

croncat info

This uses QueryMsg::GetConfig {} query, returning the data in a human readable format from the json response. The response will be type ConfigResponse.


2. Flows

These loops semi-depend on each other, as an agent cannot

1. Onboard new Agent

# Add your agent to cron known agents. (Optional: payable_account_id)

croncat register [payable_account_id]

Assuming the install generated keys, the following logic should be implemented:

  • Check if keys have been funded (Using a chain query BankQuery::AllBalances { address: Addr } or query_all_balances feature in query.) Response will contain chain native coins Vec<Coin>.

  • If enough funds, register the agent using ExecuteMsg::RegisterAgent { payable_account_id: Option<Addr> }. This TXN needs to be signed and paid by the agent. Responds with agent_status which should allow any loops to resume or wait based on the status.

2. Agent Get Rewards

# Withdraw all rewards earned for this account (Optional: payable_account_idaccount_id)

croncat withdraw [account_id]

Uses ExecuteMsg::WithdrawReward {}. This TXN needs to be signed and paid by the agent. Balance will update and can be queried normally upon completion.

3. Agent Leave

# Account to remove from list of active agents.

croncat unregister

Uses ExecuteMsg::UnregisterAgent {}. This TXN needs to be signed and paid by the agent. Agent data will be fully removed from state, chain will return any funds left on the agent balances.

4. Agent Gets Kicked

NOTE: This flow is part of the active agent flow, but occurs when an agent is no longer active on chain because of getting kicked. The chain will supply a status, denoting Active or not.


Loops

These loops are possible to run upon Agent being registered. If agent is unregistered, loops cannot run. Then, the loops can only be run sequentially: A first, then B, etc.

RUN

A. Agent Status

  • When AgentStatus::Pending: Run a status check every 1min or every 10 blocks, using the QueryMsg::GetAgent { account_id: Addr } query, and looking at the "status" field on the Agent response.
  • When AgentStatus::Nominated: Immediately perform a paid transaction to make the agent active. Uses the message ExecuteMsg::CheckInAgent {} .
  • When AgentStatus::Active: Allow "B" & "C" loops to be performed until status changes away from "Active".

B. Scheduled Tasks

  • Upon a new block, query the chain QueryMsg::GetAgentTasks { account_id: Addr } using this Agents address for account_id, the response GetAgentTasksResponse(u64, u128) indicates how many tasks need to occur this block. u64 indicates how many tasks need to get called this block, u128 indicates the slot (internal info). Given the total tasks needing to be called, it is then possible for the agent to batch or immediately multi-thread the total tasks noted.

C. Rules Tasks

Quick TLDR;

Rules allow for quering data to check if a paid transaction is necessary. You can think of this like IFTTT, where contract state is evaluating static data (that has previously changed) and resolving a standardized boolean state. The rules can then be chained (not blockchain) where the output of a query can be an input in the next query parameters. If the last rule to return determines if a paid transaction should occur. All of this logic will need to occur again on chain, for a valid execution to happen.

Loop Logic:
  • Cache all tasks containing rules locally, every 1 minute or every 10blocks. Uses QueryMsg::GetTasks {from_index: Option<u64>, limit: Option<u64>} which returns the Vec<TaskResponse>. Filter out any tasks that exclude rules field.
  • Using the cache, upon every block:
    • Evaluate each rule sequentially (ascending 0 indexed) making a query defined in the msg of the rule. Utilize the RuleResponse<T> = (bool, T) boolean field to know if the sequence should progress for another query. Use the T response data as input in the next query.
    • Once rule sequence is complete, if last rule evaluated TRUE proceed to its task execution.
    • If evaluation was FALSE stop, and proceed to the next task rules.
  • Task execution:
    • Given above rule evaluation, if the task is returning TRUE from rules, it is time to execute a paid transaction.
    • Using ExecuteMsg::ProxyCall {} message, make a paid transaction.
    • Upon complete, proceed to next rules task.