Part 1: Project Setup & Simulation

In this first part, you'll go from an empty directory to a fully initialized CRE project and simulate your first, minimal workflow. The goal is to get a quick "win" and familiarize yourself with the core project structure and development loop.

What you'll do

  • Initialize a new project using cre init.
  • Explore the generated project structure and workflow code.
  • Configure your workflow for simulation.
  • Run your first local simulation with cre workflow simulate.

Prerequisites

Before you begin, ensure you have the following:

  • CRE CLI: See the Installation Guide for details.
  • CRE account & authentication: You must have a CRE account and be logged in with the CLI. See Create your account and Log in with the CLI for instructions.
  • Go: You must have Go version 1.25.3 or higher installed. Check your version with go version. See Install Go for instructions.
  • Funded Sepolia Account: An account with Sepolia ETH to pay for transaction gas fees. Go to faucets.chain.link to get some Sepolia ETH.

Step 1: Verify your authentication

Before initializing your project, verify that you're logged in to the CRE CLI:

cre whoami

Expected output:

  • If you're authenticated, you'll see your account details:

    Account details retrieved:
    
    Email:           [email protected]
    Organization ID: org_AbCdEfGhIjKlMnOp
    
  • If you're not logged in, you'll receive an error message prompting you to run cre login:

    Error: failed to attach credentials: failed to load credentials: you are not logged in, try running cre login
    

    Run the login command and follow the prompts:

    cre login
    

    See Logging in with the CLI for detailed instructions if you need help.

Step 2: Initialize your project

The CRE CLI provides an init command to scaffold a new project. It's an interactive process that will ask you for a project name, a workflow template, and a name for your first workflow.

  1. In your terminal, navigate to a parent directory where you want your new CRE project to live.

  2. Run the init command. The CLI will guide you through the setup process:

    cre init
    
  3. Provide the following details when prompted:

    • Project name: onchain-calculator
    • Language: Select Golang and press Enter.
    • Pick a workflow template: Use the arrow keys to select Helloworld: A Golang Hello World example and press Enter. We are starting from scratch to learn all the configuration steps.
    • Workflow name: my-calculator-workflow

The CLI will then create a new onchain-calculator directory and initialize your first workflow within it.

Step 3: Explore the generated files

The init command creates a directory with a standard structure and generates your first workflow code. Let's explore what was created.

Project structure

Your new project has the following structure:

onchain-calculator/
├── contracts/
│   └── evm/
│       └── src/
│           ├── abi/
│           └── keystone/
├── my-calculator-workflow/
│   ├── config.production.json
│   ├── config.staging.json
│   ├── main.go
│   ├── README.md
│   └── workflow.yaml
├── .env
├── .gitignore
├── go.mod
├── go.sum
├── project.yaml
└── secrets.yaml
  • Project: The top-level directory (e.g., onchain-calculator/).
    • It contains project-wide files like project.yaml, which holds shared configurations for all workflows within the project.
    • The entire project is a single Go module.
    • A project can contain multiple workflows.
  • Workflow: A subdirectory (e.g., my-calculator-workflow/) that contains source code and configuration. It functions as a Go package within the main project-level Go module.

Here are the key files and their roles:

File
Role
project.yamlThe global configuration file. Contains shared settings like RPC URLs for different environments (called targets).
.envStores secrets and environment variables, like your private key. Never commit this file to version control.
go.mod/go.sumManages the dependencies for the entire project, including all workflows and contract bindings.
contracts/evm/src/abi/Directory where you place contract ABI files (.abi). These are used to generate bindings, which are type-safe Go packages that make it easy to interact with your smart contracts from your workflow. The generated bindings will be saved to a new contracts/evm/src/generated/ directory.
contracts/evm/src/keystone/Directory for Keystone-related contract files.
secrets.yamlAn empty secrets configuration file created by the CLI. You'll learn how to use this for managing secrets in more advanced guides.
my-calculator-workflow/A directory containing the source code and configuration for a single workflow. It is a package within the project's main Go module.
├── workflow.yamlContains configurations specific to this workflow, such as its name and workflow artifacts (entry point path, config file path, secrets file path). The workflow-artifacts section tells the CLI where to find your workflow's files.
├── config.staging.jsonContains parameters for your workflow when using the staging-settings target, which can be accessed in your code via the Config object.
├── config.production.jsonContains parameters for your workflow when using the production-settings target, which can be accessed in your code via the Config object.
└── main.goThe heart of your workflow where you'll write your Go logic.

You don't need to understand every file and directory right now—this guide is designed to introduce each concept when you actually need it. For now, let's look at the workflow code.

The workflow code

The init command created a main.go file with a minimal main function. Let's replace the contents of this file with the code for a basic "Hello World!" workflow.

This code defines a Config struct to hold parameters from our config file. It then configures a cron trigger to run on the schedule provided in the config, and registers a simple handler that logs a message.

Open onchain-calculator/my-calculator-workflow/main.go and replace its entire content with the following code:

onchain-calculator/my-calculator-workflow/main.go
Go
1 //go:build wasip1
2
3 package main
4
5 import (
6 "log/slog"
7
8 "github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron"
9 "github.com/smartcontractkit/cre-sdk-go/cre"
10 "github.com/smartcontractkit/cre-sdk-go/cre/wasm"
11 )
12
13 // Config struct defines the parameters that can be passed to the workflow.
14 type Config struct {
15 Schedule string `json:"schedule"`
16 }
17
18 // The result of our workflow, which is empty for now.
19 type MyResult struct{}
20
21 // onCronTrigger is the callback function that gets executed when the cron trigger fires.
22 func onCronTrigger(config *Config, runtime cre.Runtime, trigger *cron.Payload) (*MyResult, error) {
23 logger := runtime.Logger()
24 logger.Info("Hello, Calculator! Workflow triggered.")
25 return &MyResult{}, nil
26 }
27
28 // InitWorkflow is the required entry point for a CRE workflow.
29 // The runner calls this function to initialize the workflow and register its handlers.
30 func InitWorkflow(config *Config, logger *slog.Logger, secretsProvider cre.SecretsProvider) (cre.Workflow[*Config], error) {
31 return cre.Workflow[*Config]{
32 cre.Handler(
33 // Use the schedule from our config file.
34 cron.Trigger(&cron.Config{Schedule: config.Schedule}),
35 onCronTrigger,
36 ),
37 }, nil
38 }
39
40 // main is the entry point for the WASM binary.
41 func main() {
42 // The runner is initialized with our Config struct.
43 // It will automatically parse the config.json file into this struct.
44 wasm.NewRunner(cre.ParseJSON[Config]).Run(InitWorkflow)
45 }

Step 4: Configure your workflow

Now that you've explored the generated files, let's configure your workflow for simulation. You'll need to adjust a few configuration files.

Update config files

The CLI generates separate config files for each target environment. Your workflow code can access the parameters from whichever config file corresponds to the target you're using.

Inside the my-calculator-workflow directory, open config.staging.json and add the schedule parameter that our main.go code expects:

{
  "schedule": "0 */1 * * * *"
}

Since we'll be using the staging-settings target for this guide, you only need to update config.staging.json for now. The config.production.json file can remain empty.

Review workflow.yaml

This file tells the CLI where to find your workflow files. The cre init command created this file with default values. Open my-calculator-workflow/workflow.yaml and you'll see:

# ==========================================================================
staging-settings:
  user-workflow:
    workflow-name: "my-calculator-workflow-staging"
  workflow-artifacts:
    workflow-path: "."
    config-path: "./config.staging.json"
    secrets-path: ""

# ==========================================================================
production-settings:
  user-workflow:
    workflow-name: "my-calculator-workflow-production"
  workflow-artifacts:
    workflow-path: "."
    config-path: "./config.production.json"
    secrets-path: ""

Understanding the sections:

  • Target names (staging-settings, production-settings): These are environment configuration sets. The cre init command pre-populates your workflow.yaml with these two common targets as a starting point, but you can name targets whatever you want (e.g., dev, test, prod). When running CLI commands, you specify which target to use with the --target flag.
  • workflow-name: Each target has its own workflow name with a suffix (e.g., -staging, -production). This allows you to deploy the same workflow to different environments with distinct identities.
  • workflow-path: ".": The entry point for your Go code (. means the current directory)
  • config-path: Each target points to its own config file (config.staging.json or config.production.json)
  • secrets-path: "": The location of your secrets file (empty for now; you'll learn about secrets in more advanced guides)

You don't need to modify this file for now.

For this guide, we'll use staging-settings for local simulation. When you run cre workflow simulate my-calculator-workflow --target staging-settings, the CLI reads the configuration from the staging-settings section of this file.

Set up your private key

The simulator requires a private key to initialize its environment, even for workflows that don't interact with the blockchain yet. This key will be used in later parts of this guide to read from and send transactions to the Sepolia testnet.

  1. Open the .env file located in your onchain-calculator/ project root directory.

  2. Add your funded Sepolia account's private key:

    # Replace with your own private key for your funded Sepolia account
    CRE_ETH_PRIVATE_KEY=YOUR_64_CHARACTER_PRIVATE_KEY_HERE
    

Step 5: Run your first simulation

Now that your workflow is configured and dependencies are installed, you can run the simulation. Workflow simulation is a local execution environment that compiles your code to WebAssembly and runs it on your machine, allowing you to test and debug before deploying to a live network.

Run the simulate command from your project root directory (the onchain-calculator/ folder):

cre workflow simulate my-calculator-workflow --target staging-settings

This command compiles your Go code, uses the staging-settings target configuration from workflow.yaml, and spins up a local simulation environment.

Step 6: Review the output

After the workflow compiles, the simulator detects the single trigger you defined in your code and immediately runs the workflow.

Workflow compiled
2025-11-03T22:34:11Z [SIMULATION] Simulator Initialized

2025-11-03T22:34:11Z [SIMULATION] Running trigger trigger=[email protected]
2025-11-03T22:34:11Z [USER LOG] msg="Hello, Calculator! Workflow triggered."

Workflow Simulation Result:
 {}

2025-11-03T22:34:11Z [SIMULATION] Execution finished signal received
2025-11-03T22:34:11Z [SIMULATION] Skipping WorkflowEngineV2
  • [USER LOG]: This is the output from your own code—in this case, the logger.Info() call. This is where you will look for your custom log messages.
  • [SIMULATION]: These are system-level messages from the simulator showing its internal state (initialization, trigger execution, completion).
  • Workflow Simulation Result: {}: This is the final return value of your workflow. It's currently an empty object, but you will populate it in the next part of this guide.

Congratulations! You've built and simulated your first CRE workflow from scratch.

Next steps

In the next section, you'll build on this foundation by modifying the workflow to fetch real data from an external API.

Get the latest Chainlink content straight to your inbox.