workflow

package module
v0.0.0-...-21d01d2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2022 License: MIT Imports: 3 Imported by: 0

README

Nerif Automation Workflow Engine

This repository contains a logic that allows to build and serve automation workflows.

Currently, it supports only EVM-compatible chains. In the near future the following chains will be integrated:

And more others chains

Example

For more examples take a look at the examples.

Triggers

The automation workflow could you executed based on some conditions/rules which called trigger.

The following triggers are supported:

  • block-based trigger invokes a workflow execution periodically based on the current block number. For instance, it could be execution on each block (n), on each second block (2n), etc.

    {
      "kind": "BLOCK",
      "blockParams": {
        "chainID": 5,
        "period": "2n"
      }
    }
    
  • event-based trigger invokes a workflow execution based on specific event emission. The event could belong to a specific contract on a specific chain. For example, a workflow could be executed when a contract MyContract with 0x... address emmits an event MyEvent with 0x... topic ID. In the future, the trigger could be adjusted for checking specific fields values of the emmited event.

    {
      "kind": "EVENT",
      "eventParams": {
        "chainID": 80001,
        "contract": "0x.....",
        "eventABI": "TriggerPerformance(bytes,bool)"
      }
    }
    
  • cron-based trigger invokes a workflow execution periodically based on time. This is a representation of the regular cron functionality. For example, a workflow could be executed once per day by using the following cron rule: 0 0 * * *.

More triggers to be supported...

Actions

Automation workflow could do many things related to on-chain or off-chain activity such as eth calls, sending transactions, etc.

Currently, the following actions are supported:

  • eth_call allows doing ETH call to any smart contract function deployed on any EVM compatible chain. Return results could be stored into variable and then used in the next steps.

    {
        "chainID": 80001,
        "contract": "0x.....",
        "funcABI": "check(bytes data) returns (bool, bytes)",
        "params": {
          "data": "0x00"
        },
        "gasLimit": 500000
      }
    
  • eth_tx allows sending transaction to any smart contract function deployed on any EVM compatible chain.

    {
        "chainID": 5,
        "contract": "0x.....",
        "funcABI": "perform(bytes performData)",
        "params": {
          "performData": "$checkData"
        },
        "gasLimit": 500000
      }
    

For contribution please read CONTRIBUTING.md

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ChildStepRelation

type ChildStepRelation struct {
	// ID is the child step ID.
	ID string `json:"id" validate:"required"`

	// ExecuteOnError contains a boolean value to identify whether the child
	// step must be executed if the current one is failed.
	ExecuteOnError bool `json:"executeOnError,omitempty"`

	// Conditions contains a list of conditions that must be met in order to execute the child step.
	Conditions []Condition `json:"conditions,omitempty" validate:"lt=100,dive"`
}

ChildStepRelation represents a dependency object on a child step.

type Condition

type Condition struct {
	// Type contains a condition type.
	Type ConditionType `json:"type" validate:"required,condition_type"`

	// Pure contains pure condition.
	Pure *ConditionPure `json:"pure,omitempty" validate:"required_if=Type PURE"`

	// Group contains condition group.
	Group *ConditionGroup `json:"group,omitempty" validate:"required_if=Type GROUP"`
}

Condition represents a condition data object. It is allowed to have either pure or group condition filled.

type ConditionGroup

type ConditionGroup struct {
	// Operator is the condition operator that will be applied to the whole group of conditions.
	// I.e. if operator is "AND" then all conditions in the group must be met.
	Operator ConditionOperator `json:"operator" validate:"required,condition_operator"`

	// Conditions is the list of group's conditions.
	Conditions []Condition `json:"conditions" validate:"lt=100,dive"`
}

ConditionGroup contains group condition data.

type ConditionOperator

type ConditionOperator string

ConditionOperator represents a condition operator.

const (
	// ConditionOperatorAnd represents AND condition operator.
	ConditionOperatorAnd ConditionOperator = "AND"

	// ConditionOperatorOr represents OR condition operator.
	ConditionOperatorOr ConditionOperator = "OR"

	// ConditionOperatorXor represents XOR condition operator.
	ConditionOperatorXor ConditionOperator = "XOR"
)

These are condition operators.

type ConditionPure

type ConditionPure struct {
	// Left contains a left part of a condition
	Left interface{} `json:"left" validate:"required"`

	// Operator is the condition comparison operator.
	// TODO: Add validation: == <= >= <>
	Operator string `json:"operator" validate:"required"`

	// Right contains a right part of a condition
	Right interface{} `json:"right" validate:"required"`
}

ConditionPure contains pure condition data.

type ConditionType

type ConditionType string

ConditionType represents a condition type

const (
	// ConditionTypePure is the pure condition type
	ConditionTypePure ConditionType = "PURE"

	// ConditionTypeGroup is the group condition type
	ConditionTypeGroup ConditionType = "GROUP"
)

Conditions types

type ParentStepRelation

type ParentStepRelation struct {
	// ID is the parent step ID.
	ID string `json:"id" validate:"required"`

	// ExecuteOnError contains a boolean value to identify whether the current
	// step must be executed if the parent one is failed.
	ExecuteOnError bool `json:"executeOnError,omitempty"`
}

ParentStepRelation represents a dependency object from a parent step.

type Step

type Step struct {
	// ID contains step identifier
	ID string `json:"id" validate:"required"`

	// Type is the typ of the current step.
	// The value of this field identifies which of the fields below is not empty.
	Type StepType `json:"type" validate:"required,step_type"`

	// Name is the step name
	Name string `json:"name,omitempty"`

	TriggerConfig   *StepTriggerConfig   `json:"triggerConfig,omitempty" validate:"required_if=Type TRIGGER"`
	ActionConfig    *StepActionConfig    `json:"actionConfig,omitempty" validate:"required_if=Type ACTION"`
	ConditionConfig *StepConditionConfig `json:"conditionConfig,omitempty" validate:"required_if=Type CONDITION"`
	ExitConfig      *StepExitConfig      `json:"exitConfig,omitempty" validate:"required_if=Type EXIT"`

	// ParentSteps contains parent steps dependencies
	ParentSteps []ParentStepRelation `json:"parentSteps,omitempty" validate:"lt=100,dive"`

	// ChildSteps contains child steps dependencies
	ChildSteps []ChildStepRelation `json:"childSteps,omitempty" validate:"lt=100,dive"`

	// ExitOnError contains a boolean value to identify whether a workflow
	// must be failed if this particular step is failed.
	ExitOnError bool `json:"exitOnError,omitempty"`

	// Metadata contains any data.
	// This is basically used by the UI side for visualization.
	Metadata map[string]interface{} `json:"metadata"`
}

Step represents a workflow step

type StepActionConfig

type StepActionConfig struct {
	// Kind is the kind of action
	Kind StepActionKind `json:"kind" validate:"required"`

	// OutputField is the name of the field that contains a step's results.
	OutputField string `json:"outputField" validate:"variable"`

	// EthCallParams contains an ath_call event parameters.
	EthCallParams *StepActionEthCallParams `json:"ethCallParams,omitempty"`

	// EthTxParams contains an eth tx action parameters.
	EthTxParams *StepActionEthTxParams `json:"ethTxParams,omitempty"`
}

StepActionConfig contains configuration data of ACTION step type.

type StepActionEthCallParams

type StepActionEthCallParams struct {
	// ChainID is the chain ID of the contract
	ChainID uint64 `json:"chainID" validate:"required"`

	// Contract is the contract address for making eth_call
	Contract string `json:"contract" validate:"required,eth_addr"`

	// FuncAbi is the function ABI. E.g. "checkUpkeep(bytes data) returns (bool, bytes)"
	FuncAbi string `json:"funcABI" validate:"required"`

	// Params is the params mapping based on the function ABI
	Params map[string]interface{} `json:"params"`

	// GasLimit is the gas limit for the eth_call
	GasLimit uint64 `json:"gasLimit"`
}

StepActionEthCallParams contains parameters of the eth_call action

type StepActionEthTxParams

type StepActionEthTxParams struct {
	// ChainID is the chain ID of the contract
	ChainID uint64 `json:"chainID" validate:"required"`

	// Contract is the contract address for sending tx
	Contract string `json:"contract" validate:"required,eth_addr"`

	// FuncAbi is the function ABI. E.g. "performUpkeep(bytes performData)"
	FuncAbi string `json:"funcABI" validate:"required"`

	// Params is the params mapping based on the function ABI
	Params map[string]interface{} `json:"params"`

	// GasLimit is the gas limit for the tx
	GasLimit uint64 `json:"gasLimit"`
}

StepActionEthTxParams contains parameters of the eth transaction action

type StepActionKind

type StepActionKind string

StepActionKind represents a kind of action

const (
	// StepActionKindEthCall is the ETH_CALL kind of trigger
	StepActionKindEthCall StepActionKind = "ETH_CALL"

	// StepActionKindEthTx is the ETH_TX kind of trigger
	StepActionKindEthTx StepActionKind = "ETH_TX"
)

Action kinds

type StepConditionConfig

type StepConditionConfig struct {
	// OutputField is the name of the field that contains a step's results.
	OutputField string `json:"outputField" validate:"required,variable"`

	// Condition contains condition data.
	Condition Condition `json:"condition"`
}

StepConditionConfig contains configuration data of CONDITION step type.

type StepExitConfig

type StepExitConfig struct {
	// Notes contains exit step notes
	Notes string `json:"notes,omitempty"`
}

StepExitConfig contains configuration data of EXIT step type.

type StepTriggerBlockParams

type StepTriggerBlockParams struct {
	// ChainID is the chain ID the trigger is related to
	ChainID uint64 `json:"chainID" validate:"required"`

	// Period is the period of the block trigger. E.g. n, 2n, 3n, 5n, etc.
	Period string `json:"period" validate:"required"`
}

StepTriggerBlockParams contains parameters of the block trigger

type StepTriggerConfig

type StepTriggerConfig struct {
	// Kind is the kind of trigger
	Kind StepTriggerKind `json:"kind" validate:"required,trigger_type"`

	// OutputField is the name of the field that contains a step's results.
	OutputField string `json:"outputField" validate:"required,variable"`

	// BlockParams contains a block trigger parameters.
	BlockParams *StepTriggerBlockParams `json:"blockParams,omitempty" validate:"required_if=Kind BLOCK"`

	// EventParams contains a event trigger parameters.
	EventParams *StepTriggerEventParams `json:"eventParams,omitempty" validate:"required_if=Kind EVENT"`

	// CronParams contains a cron trigger parameters.
	CronParams *StepTriggerCronParams `json:"cronParams,omitempty" validate:"required_if=Kind CRON"`
}

StepTriggerConfig contains configuration data of TRIGGER step type.

type StepTriggerCronParams

type StepTriggerCronParams struct {
	// Rule is the cron rule, e.g. "0 * * * *"
	Rule string `json:"rule" validate:"required,cron"`
}

StepTriggerCronParams contains parameters of the cron trigger

type StepTriggerEventParams

type StepTriggerEventParams struct {
	// ChainID is the chain ID the trigger is related to
	ChainID uint64 `json:"chainID"`

	// Contract is the contract address that emmits an event
	Contract string `json:"contract"`

	// EventABI is the event ABI, e.g. "TriggerPerformance(bytes,bool)"
	// It should be provided if topicID is empty
	EventABI *string `json:"eventABI" validate:"required_without=TopicID" `

	// TopicID is the topic ID that starts from 0x...
	// It should be provided if eventABI is empty
	TopicID *string `json:"topicID" validate:"required_without=EventABI,hexadecimal" `
}

StepTriggerEventParams contains parameters of the event trigger

type StepTriggerKind

type StepTriggerKind string

StepTriggerKind represents a kind of trigger

const (
	// StepTriggerKindBlock is the BLOCK kind of trigger
	StepTriggerKindBlock StepTriggerKind = "BLOCK"

	// StepTriggerKindEvent is the EVENT kind of trigger
	StepTriggerKindEvent StepTriggerKind = "EVENT"

	// StepTriggerKindCron is the CRON kind of trigger
	StepTriggerKindCron StepTriggerKind = "CRON"
)

Trigger kinds

type StepType

type StepType string

StepType represents a step type.

const (
	// StepTypeTrigger represents an TRIGGER step type.
	StepTypeTrigger StepType = "TRIGGER"

	// StepTypeAction represents an ACTION step type.
	StepTypeAction StepType = "ACTION"

	// StepTypeCondition represents an CONDITION step type.
	StepTypeCondition StepType = "CONDITION"

	// StepTypeExit represents an EXIT step type.
	StepTypeExit StepType = "EXIT"
)

Step types

type Workflow

type Workflow struct {
	// ID is the workflow identifier
	ID string `json:"id" validate:"required"`

	// Steps list of the workflow
	Steps []Step `json:"steps" validate:"dive"`

	// Metadata contains any data.
	// This is basically used by the UI side for visualization.
	Metadata map[string]interface{} `json:"metadata"`
}

Workflow is the high level workflow model

func (*Workflow) Scan

func (a *Workflow) Scan(value interface{}) error

Scan is the custom implementation of sql.Scanner

func (Workflow) Value

func (a Workflow) Value() (driver.Value, error)

Value is the custom implementation of sql.Valuer

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL