This template provides an end-to-end starting point for bringing your own custom data feed on-chain with the Chainlink Runtime Environment (CRE). It showcases local simulation and the core CRE workflow patterns.
Quick navigation:
What This Template Does
Components:
- Contracts (Solidity) under
projectRoot/contracts/evm/src
Example demo contracts used by the workflow:ReserveManagerSimpleERC20BalanceReaderMessageEmitter
- CRE Workflow that fetches your off-chain data and optionally performs chain writes based on configurable triggers (cron or EVM log).
Key Technologies:
- CRE (Chainlink Runtime Environment) – orchestrates workflows with DON consensus.
TypeScript Implementation
Getting Started with TypeScript
1 Update .env file
You need to add a private key to the .env file. This is specifically required if you want to simulate chain writes (the key must be valid and funded).
If your workflow does not write on-chain, you can keep a dummy key:
CRE_ETH_PRIVATE_KEY=0000000000000000000000000000000000000000000000000000000000000001
2 Install dependencies
If Bun is not already installed, follow the instructions at: https://bun.sh/docs/installation
From your project root, run:
bun install --cwd ./my-workflow
3 Configure RPC endpoints
For local simulation to interact with a chain, specify RPC endpoints for the chains you interact with in project.yaml. This is required for submitting transactions and reading blockchain state.
Supported for local simulation (testnet/mainnet variants):
- Ethereum (
ethereum-testnet-sepolia,ethereum-mainnet) - Base (
ethereum-testnet-sepolia-base-1,ethereum-mainnet-base-1) - Avalanche (
avalanche-testnet-fuji,avalanche-mainnet) - Polygon (
polygon-testnet-amoy,polygon-mainnet) - BNB Chain (
binance-smart-chain-testnet,binance-smart-chain-mainnet) - Arbitrum (
ethereum-testnet-sepolia-arbitrum-1,ethereum-mainnet-arbitrum-1) - Optimism (
ethereum-testnet-sepolia-optimism-1,ethereum-mainnet-optimism-1)
Add your RPCs under rpcs (example):
rpcs:
- chain-name: ethereum-testnet-sepolia
url: <Your RPC endpoint to ETH Sepolia>
For chain names, see the selectors list: chain-selectors/selectors.yml
4 Deploy contracts
Deploy the demo contracts: BalanceReader, MessageEmitter, ReserveManager, SimpleERC20. You can deploy to a local chain or a testnet using tools like Foundry.
For a quick start, you can also use the pre-deployed contract addresses on Ethereum Sepolia—no action required if you're just trying things out.
5 Configure workflow
Configure config.json for the workflow:
schedule: e.g."*/30 * * * * *"(every 30 seconds), or any cron you preferurl: your off-chain data endpoint (custom data feed)tokenAddress:SimpleERC20contract addressporAddress:ReserveManagercontract addressproxyAddress:UpdateReservesProxySimplifiedcontract addressbalanceReaderAddress:BalanceReadercontract addressmessageEmitterAddress:MessageEmittercontract addresschainSelectorName: human-readable chain name (see selectors YAML linked above)gasLimit: gas limit used for chain writes
Ensure workflow.yaml points to the config:
staging-settings:
user-workflow:
workflow-name: "my-workflow"
workflow-artifacts:
workflow-path: "./main.ts"
config-path: "./config.json"
secrets-path: ""
6 Simulate the workflow
Run the command from the project root and pass the path to the workflow directory:
cre workflow simulate <path-to-workflow-directory>
Example (for my-workflow):
cre workflow simulate my-workflow
You'll see trigger options similar to:
🚀 Workflow simulation ready. Please select a trigger:
1. [email protected] Trigger
2. evm:ChainSelector:[email protected] LogTrigger
- Cron Trigger: choose
1→ the workflow executes on the schedule. - Log Trigger: choose
2, then provide the example inputs:
Transaction Hash: 0x420721d7d00130a03c5b525b2dbfd42550906ddb3075e8377f9bb5d1a5992f8e
Log Event Index: 0
Go Implementation
Getting Started with Go
1 Update .env file
Add a private key to .env. This is required if your workflow performs chain writes (must be valid and funded).
If your workflow does not write on-chain, you can use a dummy key:
CRE_ETH_PRIVATE_KEY=0000000000000000000000000000000000000000000000000000000000000001
2 Configure RPC endpoints
Specify RPC endpoints for chains you interact with in project.yaml. This is needed to submit transactions and read state.
Supported for local simulation (testnet/mainnet variants):
- Ethereum (
ethereum-testnet-sepolia,ethereum-mainnet) - Base (
ethereum-testnet-sepolia-base-1,ethereum-mainnet-base-1) - Avalanche (
avalanche-testnet-fuji,avalanche-mainnet) - Polygon (
polygon-testnet-amoy,polygon-mainnet) - BNB Chain (
binance-smart-chain-testnet,binance-smart-chain-mainnet) - Arbitrum (
ethereum-testnet-sepolia-arbitrum-1,ethereum-mainnet-arbitrum-1) - Optimism (
ethereum-testnet-sepolia-optimism-1,ethereum-mainnet-optimism-1)
Add your RPC under rpcs:
rpcs:
- chain-name: ethereum-testnet-sepolia
url: <Your RPC endpoint to ETH Sepolia>
3 Deploy contracts
Deploy the demo contracts: BalanceReader, MessageEmitter, ReserveManager, SimpleERC20 (locally or to a testnet using tools like Foundry).
For quick trials, you can use the pre-deployed addresses on Ethereum Sepolia:
- chain:
ethereum-testnet-sepolia ReserveManager:0x073671aE6EAa2468c203fDE3a79dEe0836adF032SimpleERC20:0x4700A50d858Cb281847ca4Ee0938F80DEfB3F1ddBalanceReader:0x4b0739c94C1389B55481cb7506c62430cA7211CfMessageEmitter:0x1d598672486ecB50685Da5497390571Ac4E93FDc
Source code lives under projectRoot/contracts/evm/src.
4 Generate contract bindings
Generate Go bindings from ABIs (located in projectRoot/contracts/src/abi).
Run this from your project root (where project.yaml is):
# Generate bindings for all contracts
cre generate-bindings evm
Bindings will appear under contracts/evm/src/generated/, e.g.:
contracts/evm/src/generated/ierc20/IERC20.gocontracts/evm/src/generated/reserve_manager/ReserveManager.gocontracts/evm/src/generated/balance_reader/BalanceReader.go
(Template bindings are pre-generated; re-run only if ABIs/contracts change.)
5 Configure workflow
Edit config.json:
schedule: e.g."*/3 * * * * *"(every 3 seconds) or your preferred cronurl: your off-chain data endpoint (custom data feed)tokenAddress:SimpleERC20addressreserveManagerAddress:ReserveManageraddressbalanceReaderAddress:BalanceReaderaddressmessageEmitterAddress:MessageEmitteraddresschainName: selected chain name (see selectors YAML linked above)gasLimit: gas limit used for chain writes
Ensure workflow.yaml points to the config:
staging-settings:
user-workflow:
workflow-name: "my-workflow"
workflow-artifacts:
workflow-path: "."
config-path: "./config.json"
secrets-path: ""
6 Simulate the workflow
From your project root:
cre workflow simulate my-workflow
You'll see trigger options, e.g.:
🚀 Workflow simulation ready. Please select a trigger:
1. [email protected] Trigger
2. evm:ChainSelector:[email protected] LogTrigger
- Cron Trigger: choose
1→ the workflow executes immediately on the schedule. - Log Trigger: choose
2→ provide the example inputs:
Transaction Hash: 0x420721d7d00130a03c5b525b2dbfd42550906ddb3075e8377f9bb5d1a5992f8e
Log Event Index: 0
Security Considerations
- Demo project – Not production-ready.
- Demo contracts – Not audited; do not use as-is in production.
- Use your own RPCs – For stability and performance, prefer private RPCs for deployment and chain writes.
- Secrets hygiene – Keep real secrets out of version control; use secure secret managers for
.envvalues.
CREATED BY CHAINLINK LABS