Documentation
¶
Overview ¶
Package workflows provides common utilities for CRE (Chainlink Runtime Environment) event watcher workflow development. It is used by CREC workflow extensions that listen for EVM contract events and post verifiable events to CREC.
Key Features ¶
- Configuration parsing — ParseWorkflowConfig for YAML/JSON workflow configs
- Event processing — BuildEVMEventFromLog, BuildVerifiableEventForEVMEvent, SignAndPostVerifiableEvent
- Workflow initialization — InitEventListenerWorkflow wires EVM log triggers with LogHandler
- Testing utilities — PrepareTestingRuntime for unit tests
Usage ¶
Create a workflow entry point:
r := wasm.NewRunner(workflows.ParseWorkflowConfig)
r.Run(func(cfg *workflows.Config, _ *slog.Logger, _ cre.SecretsProvider) (cre.Workflow[*workflows.Config], error) {
return workflows.InitEventListenerWorkflow(cfg, OnLog)
})
Implement a LogHandler that decodes the EVM log, builds a verifiable event, and posts it:
func OnLog(cfg *workflows.Config, rt cre.Runtime, payload *evm.Log) (string, error) {
evmEvent, err := workflows.BuildEVMEventFromLog(rt, cfg, payload)
if err != nil { return "", err }
eventName, err := workflows.GetEventNameFromLog(cfg, payload, abiJSON)
if err != nil { return "", err }
ve, err := workflows.BuildVerifiableEventForEVMEvent(cfg, evmEvent, cfg.Service, eventName, nil)
if err != nil { return "", err }
return workflows.SignAndPostVerifiableEvent(cfg, rt, ve)
}
Error Handling ¶
Errors from ParseWorkflowConfig indicate invalid YAML/JSON or missing required fields (e.g. chainSelector). GetContractABI returns an error if the contract is not found in config. SignAndPostVerifiableEvent returns errors from consensus generation or CREC API failures.
Index ¶
- Variables
- func BuildEVMEventFromLog(rt cre.Runtime, cfg *Config, payload *evm.Log) (*models.EVMEvent, error)
- func BuildVerifiableEventForEVMEvent(cfg *Config, ev *models.EVMEvent, service *string, name string, ...) (*models.VerifiableEvent, error)
- func CheckResponse(resp *httpcap.Response) (*httpcap.Response, error)
- func ComputeEventHash(encoded string) (common.Hash, error)
- func ConfidenceLevelFromString(s string) evm.ConfidenceLevel
- func CursorFromPB(blockNumber *pb.BigInt, logIndex uint64, txHash string) string
- func DecodeEventParams(abiJSON, eventName string, log *evm.Log) (map[string]any, error)
- func DecodeVerifiableEvent(encoded string) (*models.VerifiableEvent, error)
- func EncodeVerifiableEvent(ve *models.VerifiableEvent) (string, error)
- func EnsureChainSelector(cfg *Config, fallback string) string
- func GetBlockTimestamp(rt cre.Runtime, chainSelector string, blockNumber *pb.BigInt) uint64
- func GetContractABI(cfg *Config, contractName string) (string, error)
- func GetCurrencyCode(currencyId uint8) string
- func GetEventNameFromLog(cfg *Config, payload *evm.Log, abiJSON string) (string, error)
- func GetEventSignature(cfg *Config, eventName string) string
- func InitEventListenerWorkflow(cfg *Config, handler LogHandler) (cre.Workflow[*Config], error)
- func MustEvent(abiJSON, eventName string) gethAbi.Event
- func NewEVMLogFilter(contractAddr string, eventSigHashes [][]byte, confidence evm.ConfidenceLevel) *evm.FilterLogTriggerRequest
- func PBToUint64(b *pb.BigInt) uint64
- func ParseChainSelector(chainSelectorStr *string) (*uint64, error)
- func PrepareTestingRuntime(t *testing.T) *testutils.TestRuntime
- func Retry[T any](logger *slog.Logger, name string, rc *RetryConfig, fn func() (T, error)) (T, error)
- func SanitiseJSON(v any) any
- func SignAndPostVerifiableEvent(cfg *Config, rt cre.Runtime, ve *models.VerifiableEvent) (string, error)
- func StopRetry(err error) error
- func TxHashFromLog(l *evm.Log) string
- type Config
- type ContractDef
- type ContractReaderConfig
- type DetectEventTriggerConfig
- type Fixed2
- type LogHandler
- type OffChainReferenceData
- type OffChainReferenceDataSource
- type OnChainReferenceData
- type OnChainReferenceDataSource
- type PaymentCallback
- type PaymentRequest
- type RawMessageType
- type ReferenceData
- type RetryConfig
- type TypeAndValue
Constants ¶
This section is empty.
Variables ¶
var CurrencyCodes = map[uint8]string{}/* 179 elements not displayed */
CurrencyCodes maps ISO 4217 numeric currency IDs to their three-letter codes.
var ErrNilVerifiableEvent = errors.New("verifiable event cannot be nil")
ErrNilVerifiableEvent is returned when a nil VerifiableEvent is passed to EncodeVerifiableEvent.
Functions ¶
func BuildEVMEventFromLog ¶
BuildEVMEventFromLog constructs an EVMEvent from the given evm.Log payload, decoding parameters using the contract ABI specified in cfg.
func BuildVerifiableEventForEVMEvent ¶
func BuildVerifiableEventForEVMEvent( cfg *Config, ev *models.EVMEvent, service *string, name string, data *map[string]interface{}, ) (*models.VerifiableEvent, error)
BuildVerifiableEventForEVMEvent constructs a VerifiableEvent for the given EVMEvent, with the specified service (optional, can be nil for workflows not scoped to a service), name, and additional data.
func CheckResponse ¶
CheckResponse validates the httpcap response and returns it unchanged if acceptable.
func ComputeEventHash ¶
ComputeEventHash returns the Keccak256 hash of the encoded string as a common.Hash. The encoded string is typically the base64 output from EncodeVerifiableEvent.
func ConfidenceLevelFromString ¶ added in v0.0.16
func ConfidenceLevelFromString(s string) evm.ConfidenceLevel
func CursorFromPB ¶
CursorFromPB builds a "block-logIndex-txHash" cursor string from pb.BigInt block-number, a log-index, and an optional tx-hash. If txHash is empty, "0x" is used to match existing consumers.
func DecodeEventParams ¶
DecodeEventParams decodes an EVM log's topics/data into a named parameter map, using the provided ABI JSON and event-name. It returns parameters with snake_case keys and values sanitised via SanitiseJSON. It always returns a params map (possibly empty) even when an error occurs parsing ABI or event.
func DecodeVerifiableEvent ¶
func DecodeVerifiableEvent(encoded string) (*models.VerifiableEvent, error)
DecodeVerifiableEvent decodes a base64-encoded JSON string into a VerifiableEvent. It returns an error if the input is not valid base64 or if JSON unmarshaling fails.
func EncodeVerifiableEvent ¶
func EncodeVerifiableEvent(ve *models.VerifiableEvent) (string, error)
EncodeVerifiableEvent marshals the VerifiableEvent to JSON and encodes it as base64. It returns ErrNilVerifiableEvent if ve is nil.
func EnsureChainSelector ¶
EnsureChainSelector returns cfg.ChainSelector if set, otherwise returns the provided fallback.
func GetBlockTimestamp ¶
GetBlockTimestamp fetches the block timestamp via EVM HeaderByNumber; falls back to current UTC time if unavailable.
func GetContractABI ¶
GetContractABI returns the ABI string for the specified contract-name. Only the canonical "contractABI" field is supported.
func GetCurrencyCode ¶
GetCurrencyCode returns the three-letter ISO 4217 code for the given numeric currency ID, or "Unknown" if the ID is not found in CurrencyCodes.
func GetEventNameFromLog ¶
GetEventNameFromLog identifies the event name matching the log's topic hash by checking against the list of configured ContractEventNames and the ABI.
func GetEventSignature ¶
GetEventSignature returns the ABI event signature (topic hash) for the given event name from the workflow config. It returns an empty string if the contract ABI cannot be loaded, parsed, or if the event is not found.
func InitEventListenerWorkflow ¶
InitEventListenerWorkflow wires the standard EVM Log trigger for event-listener workflows and attaches the provided handler. It resolves the event signatures from the ABI for all events in ContractEventNames and uses cfg.ChainSelector (required in the config).
func NewEVMLogFilter ¶
func NewEVMLogFilter(contractAddr string, eventSigHashes [][]byte, confidence evm.ConfidenceLevel) *evm.FilterLogTriggerRequest
NewEVMLogFilter returns a FilterLogTriggerRequest for a single-address subscription for one or more events. Includes wildcard slots for up to 3 indexed parameters. Confidence is chosen by the caller.
func PBToUint64 ¶
PBToUint64 converts a protobuf BigInt (unsigned) to a uint64.
func ParseChainSelector ¶
ParseChainSelector validates and parses a chain_selector string parameter to uint64. Returns the parsed value or an error if the string is invalid.
func PrepareTestingRuntime ¶
func PrepareTestingRuntime(t *testing.T) *testutils.TestRuntime
PrepareTestingRuntime creates a test runtime with standard secrets configured.
func Retry ¶
func Retry[T any](logger *slog.Logger, name string, rc *RetryConfig, fn func() (T, error)) (T, error)
Retry is a generic helper to retry operations up to a fixed number of times. It uses an exponential backoff strategy; the starting delay comes from rc (see RetryConfig). If the operation fails after all attempts are exhausted, it returns the last error wrapped with context. It stops retrying immediately if the function returns an error wrapped with StopRetry.
func SanitiseJSON ¶
SanitiseJSON transforms keys to snake_case and encodes []byte or base64-like strings as 0x-hex. big.Int is rendered as string to avoid 64-bit precision loss. Additionally, fixed-size byte arrays (e.g. [32]byte) are encoded as 0x-hex. For JSON-derived []interface{} representing byte arrays (length 20 or 32), encode as 0x-hex as well.
func SignAndPostVerifiableEvent ¶
func SignAndPostVerifiableEvent(cfg *Config, rt cre.Runtime, ve *models.VerifiableEvent) (string, error)
SignAndPostVerifiableEvent performs identical-consensus report generation and posts the signed event to the Courier /onchain-watcher-events endpoint. It returns the base64 verifiable event.
func TxHashFromLog ¶
TxHashFromLog returns the 0x-hex transaction hash from a log if present; otherwise "0x".
Types ¶
type Config ¶
type Config struct {
Network string `yaml:"network" json:"network"`
CourierURL string `yaml:"courierURL" json:"courierURL"`
Service *string `yaml:"service,omitempty" json:"service,omitempty"`
ApiKeySecret string `yaml:"apiKeySecret,omitempty" json:"apiKeySecret,omitempty"`
ChainSelector string `yaml:"chainSelector" json:"chainSelector"`
WatcherID string `yaml:"watcherID" json:"watcherID"`
WorkflowName string `yaml:"workflowName" json:"workflowName"`
// ConfidenceLevel is the EVM log trigger confidence: "finalized", "safe", or "latest".
// Defaults to "latest" when omitted after [ParseWorkflowConfig].
ConfidenceLevel string `yaml:"confidenceLevel,omitempty" json:"confidenceLevel,omitempty"`
DetectEventTriggerConfig DetectEventTriggerConfig `yaml:"detectEventTriggerConfig" json:"detectEventTriggerConfig"`
}
Config is the shared configuration for all event-detection workflows (YAML or JSON). It mirrors the structure produced by our existing config.tmpl files and remains compatible with server-side gomplate rendering used during e2e runs.
func ParseWorkflowConfig ¶
ParseWorkflowConfig accepts YAML or JSON and returns a Config. chainSelector is expected to be provided by the workflow config.
type ContractDef ¶
type ContractDef struct {
ContractABI any `yaml:"contractABI" json:"contractABI"`
}
ContractDef holds the ABI string in "contractABI".
type ContractReaderConfig ¶
type ContractReaderConfig struct {
Contracts map[string]ContractDef `yaml:"contracts" json:"contracts"`
}
ContractReaderConfig contains the contracts map. We only need contractABI for this workflow.
type DetectEventTriggerConfig ¶
type DetectEventTriggerConfig struct {
ContractName string `yaml:"contractName" json:"contractName"`
ContractAddress string `yaml:"contractAddress" json:"contractAddress"`
ContractEventNames []string `yaml:"contractEventNames" json:"contractEventNames"`
ContractReaderConfig ContractReaderConfig `yaml:"contractReaderConfig" json:"contractReaderConfig"`
}
DetectEventTriggerConfig matches the template data for the log trigger.
type Fixed2 ¶
type Fixed2 float64
Fixed2 represents a fixed-point decimal number with 2 decimal places, stored as a string.
func (Fixed2) MarshalJSON ¶
MarshalJSON marshals the Fixed2 value to a JSON string.
func (*Fixed2) UnmarshalJSON ¶
UnmarshalJSON unmarshals the Fixed2 value from a JSON string.
type LogHandler ¶
LogHandler is the function signature implemented by each event-listener workflow's per-project handler (e.g. OnLog, OnCoordinatorLog). It processes an EVM log and returns a base64-encoded verifiable event (or empty string) and an error.
type OffChainReferenceData ¶
type OffChainReferenceData struct {
Source OffChainReferenceDataSource `json:"source"` // The source of the off-chain reference data.
Data map[string]any `json:"data"` // The data returned from the source call.
}
OffChainReferenceData is a structured set of fields that can be used for reference data from off-chain sources.
func GetCurrencyCodeAsOffChainReferenceData ¶
func GetCurrencyCodeAsOffChainReferenceData(currencyId uint8) OffChainReferenceData
GetCurrencyCodeAsOffChainReferenceData returns an OffChainReferenceData struct containing the currency code for the given numeric ID, or "Unknown" if the ID is not in CurrencyCodes.
type OffChainReferenceDataSource ¶
type OffChainReferenceDataSource struct {
Type string `json:"type"` // The type of the off-chain reference data.
Identifier string `json:"identifier"` // Typically the URN for the off-chain source or identifier of the standardised data format.
}
OffChainReferenceDataSource is the source of the off-chain reference data.
type OnChainReferenceData ¶
type OnChainReferenceData struct {
Source OnChainReferenceDataSource `json:"source"` // The source of the on-chain reference data.
Data map[string]any `json:"data"` // The data returned from the source call.
}
OnChainReferenceData is a structured set of fields that can be used for reference data from on-chain sources.
type OnChainReferenceDataSource ¶
type OnChainReferenceDataSource struct {
ContractAddress string `json:"contract_address"` // The contract address to call.
ContractFunctionSignature string `json:"contract_function_signature"` // The function signature to call.
CallData string `json:"call_data"` // The call data to pass to the function.
Block string `json:"block"` // The block number to call the function at.
}
OnChainReferenceDataSource is the source of the on-chain reference data.
type PaymentCallback ¶
type PaymentCallback struct {
ContractAddress string `json:"contractAddress,omitempty"` // The contract address to call. If empty, uses ApplicationAddr from PaymentRequest.
FunctionName string `json:"functionName,omitempty"` // The name of the function to call.
FunctionSignature string `json:"functionSignature,omitempty"` // The ABI function signature to call (e.g., "fulfillPayment(bytes32,uint256)")
}
PaymentCallback specifies how to call back to the application after payment processing.
type PaymentRequest ¶
type PaymentRequest struct {
ApplicationType string `json:"applicationType"` // The type of the application that generates the payment request.
ApplicationAddr string `json:"applicationAddr"` // The application that generates the payment request.
E2EID string `json:"e2eId"` // The E2E ID of the payment request.
Sender string `json:"sender"` // The sender of the payment request.
Receiver string `json:"receiver"` // The receiver of the payment.
Currency string `json:"currency"` // The currency of the payment.
Amount Fixed2 `json:"amount"` // The amount of the payment in fixed-point decimal format with 2 decimal places.
Expiration *int64 `json:"expiration,omitempty"` // The expiration time of the payment request in seconds since epoch.
CustomCallback *PaymentCallback `json:"customCallback,omitempty"` // The custom callback to be used for the payment request.
}
PaymentRequest contains the details needed for an off-chain payment request.
type RawMessageType ¶
type RawMessageType string
RawMessageType identifies the kind of payload in a TypeAndValue structure.
const ( // RawMessageTypePaymentRequest indicates the value is a payment request payload. RawMessageTypePaymentRequest RawMessageType = "payment_request" // RawMessageTypeReferenceData indicates the value is reference data from on-chain or off-chain sources. RawMessageTypeReferenceData RawMessageType = "reference_data" )
const ( // RawMessageTypeMap indicates the value is a generic map structure. RawMessageTypeMap RawMessageType = "map" )
type ReferenceData ¶
type ReferenceData struct {
OnChain []OnChainReferenceData `json:"on_chain,omitempty"` // The on-chain reference data.
OffChain []OffChainReferenceData `json:"off_chain,omitempty"` // The off-chain reference data.
Requests []TypeAndValue `json:"requests,omitempty"` // The requests to be forwarded to the off-chain applications.
}
ReferenceData is a structured set of fields that can be used for reference data from on-chain and off-chain sources as well as requests to be forwarded to off-chain applications.
func GetReferenceDataFromVerifiableEvent ¶
func GetReferenceDataFromVerifiableEvent(verifiableEvent models.VerifiableEvent) (*ReferenceData, error)
GetReferenceDataFromVerifiableEvent extracts the ReferenceData from the verifiable event data field if it exists.
type RetryConfig ¶ added in v0.0.16
type RetryConfig struct {
MaxAttempts int `yaml:"maxAttempts,omitempty" json:"maxAttempts,omitempty"`
InitialDelay string `yaml:"initialDelay,omitempty" json:"initialDelay,omitempty"`
}
RetryConfig controls how many times Retry runs fn and how long to wait between retries.
Management and defaults:
- Pass nil for rc to use the library defaults (3 attempts, initial delay 5s).
- Pass a non-nil value to override; fields that are "unset" fall back to the same defaults: MaxAttempts less than or equal to 0 means 3; InitialDelay "" or a string that time.ParseDuration rejects means 5s.
- InitialDelay must be a duration string accepted by ParseDuration (e.g. "5s", "1s", "500ms").
Workflows that load retry settings from their own YAML/JSON can define a struct that embeds or duplicates these fields with the same tags, then pass the populated *RetryConfig into Retry. Exponential backoff doubles the delay after each failed attempt (after the first).
type TypeAndValue ¶
type TypeAndValue struct {
Type RawMessageType `json:"type"`
Value json.RawMessage `json:"value"`
}
TypeAndValue is a type that holds a type and a value.