ChainlinkCREAdapterLib
Title: ChainlinkCREAdapterLib
Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from the Chainlink CRE consumer-contract guide
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
| Name | Type | Description |
|---|---|---|
| $ | 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
| Name | Type | Description |
|---|---|---|
| <none> | address |
isWorkflowAllowed
Returns whether workflowId is allowed to write reports.
function isWorkflowAllowed(bytes32 workflowId) internal view returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| workflowId | bytes32 | The CRE workflow id. |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
getLatestReport
Returns the latest report stored for workflowId.
function getLatestReport(bytes32 workflowId) internal view returns (bytes memory report, uint256 timestamp);Parameters
| Name | Type | Description |
|---|---|---|
| workflowId | bytes32 | The CRE workflow id. |
Returns
| Name | Type | Description |
|---|---|---|
| report | bytes | The ABI-encoded report payload (empty if none stored). |
| timestamp | uint256 | The 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
| Name | Type | Description |
|---|---|---|
| forwarder | address | The 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
| Name | Type | Description |
|---|---|---|
| workflowId | bytes32 | The CRE workflow id. |
| allowed | bool | True 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
| Name | Type | Description |
|---|---|---|
| metadata | bytes | Packed workflow identity (workflowId, workflowName, workflowOwner) + report id. |
| report | bytes | The 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
| Name | Type | Description |
|---|---|---|
| metadata | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| workflowId | bytes32 | |
| workflowOwner | address | |
| reportId | bytes2 |