Skip to content
Lattice

ChainlinkCREAdapterLib

Git Source

Title: ChainlinkCREAdapterLib

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from the Chainlink CRE consumer-contract guide

(https://docs.chain.link/cre/guides/workflow/using-evm-client/onchain-write/building-consumer-contracts)

Library implementing a Chainlink CRE (Chainlink Runtime Environment) workflow-report receiver. The KeystoneForwarder validates the DON's report signatures off-chain, then calls onReport, which is gated to the configured forwarder AND to an admin-allowlisted workflow id. The latest report per workflow is stored; consumer facets inheriting ChainlinkCREAdapter should override onReport (calling super.onReport first) to act on the decoded report.

IMPLEMENTATION NOTE — this follows the guide's "Direct IReceiver Implementation" path, NOT its ReceiverTemplate base contract. ReceiverTemplate is an Ownable, constructor-initialized standalone contract (constructor(address forwarder) Ownable(msg.sender)) and is structurally incompatible with a Lattice Diamond facet, which is stateless (initialized via __ChainlinkCREAdapter_init, no constructor), keeps state in ERC-7201 namespaced storage, gates on AccessControl roles (DEFAULT_ADMIN_ROLE) rather than Ownable, and registers ERC-165 through the shared diamond ERC165Lib map. Each ReceiverTemplate feature is re-created here, adapted to that model: its onlyForwarder modifier -> the msg.sender == forwarder check; its constructor forwarder + setForwarderAddress -> setForwarder; its optional setExpectedWorkflowId validation -> the mandatory setWorkflow allowlist (the workflow id already binds owner + name + workflow binary, so per-field owner/name checks are unnecessary); its _decodeMetadata helper -> _decodeMetadata here; and its abstract _processReport(bytes) hook -> the stored latest report plus the virtual onReport that consumer facets override (the same callback pattern as the other Lattice adapters). There is therefore intentionally no _processReport function in this module.

Constants

_METADATA_LENGTH

The KeystoneForwarder always delivers 64-byte metadata: 62 packed bytes (workflowId ++ workflowName ++ workflowOwner) plus a trailing 2-byte report id.

uint256 private constant _METADATA_LENGTH = 64;

Functions

chainlinkCREAdapterStorage

Returns the ERC-7201 storage struct for ChainlinkCREAdapter.

function chainlinkCREAdapterStorage() internal pure returns (ChainlinkCREAdapterStorage storage $);

Returns

NameTypeDescription
$ChainlinkCREAdapterStorage

__ChainlinkCREAdapter_init

Registers the canonical IReceiver ERC-165 interface.

Must be called between preInitializer / postInitializer.

function __ChainlinkCREAdapter_init() internal;

registerInterface

Writes true to the ERC-165 map slot for the canonical IReceiver id.

function registerInterface() internal;

getForwarder

Returns the configured KeystoneForwarder.

function getForwarder() internal view returns (address);

Returns

NameTypeDescription
<none>address

isWorkflowAllowed

Returns whether workflowId is allowed to write reports.

function isWorkflowAllowed(bytes32 workflowId) internal view returns (bool);

Parameters

NameTypeDescription
workflowIdbytes32The CRE workflow id.

Returns

NameTypeDescription
<none>bool

getLatestReport

Returns the latest report stored for workflowId.

function getLatestReport(bytes32 workflowId) internal view returns (bytes memory report, uint256 timestamp);

Parameters

NameTypeDescription
workflowIdbytes32The CRE workflow id.

Returns

NameTypeDescription
reportbytesThe ABI-encoded report payload (empty if none stored).
timestampuint256The block timestamp when the report was received (0 if none).

setForwarder

Sets or replaces the KeystoneForwarder.

Caller must hold DEFAULT_ADMIN_ROLE. Reverts CREInvalidForwarder on the zero address.

function setForwarder(address forwarder) internal;

Parameters

NameTypeDescription
forwarderaddressThe forwarder allowed to call onReport.

setWorkflow

Allows or disallows a workflow id from writing reports.

Caller must hold DEFAULT_ADMIN_ROLE. Reverts CREInvalidWorkflowId on a zero id.

function setWorkflow(bytes32 workflowId, bool allowed) internal;

Parameters

NameTypeDescription
workflowIdbytes32The CRE workflow id.
allowedboolTrue to allow, false to disallow.

onReport

Called by the KeystoneForwarder to deliver a CRE workflow report.

Authenticates the forwarder by its address (msg.sender), decodes the packed metadata, checks the workflow id against the allowlist, stores the latest report, and emits ReportReceived.

NOTE: This function only manages bookkeeping. Consumer facets that inherit ChainlinkCREAdapter should override onReport (calling super.onReport first) to act on the delivered report.

function onReport(bytes calldata metadata, bytes calldata report) internal;

Parameters

NameTypeDescription
metadatabytesPacked workflow identity (workflowId, workflowName, workflowOwner) + report id.
reportbytesThe ABI-encoded workflow payload.

_decodeMetadata

Decodes the KeystoneForwarder metadata, packed as abi.encodePacked(bytes32 workflowId, bytes10 workflowName, address workflowOwner) with a trailing 2-byte report id.

Caller must ensure metadata.length >= 64. workflowName is intentionally not returned.

function _decodeMetadata(bytes calldata metadata)
        private
        pure
        returns (bytes32 workflowId, address workflowOwner, bytes2 reportId);

Parameters

NameTypeDescription
metadatabytes

Returns

NameTypeDescription
workflowIdbytes32
workflowOwneraddress
reportIdbytes2