Skip to main content

CRE Simulation

Chainlink's CRE CLI provides a local simulation environment for testing GHOST's confidential workflows without deploying to the DON.

Prerequisites

Install the CRE CLI:

npm install -g @chainlink/cre-cli

Verify installation:

cre --version

Simulating Workflows

Settle Loans

cd ghost-settler
cre workflow simulate ./settle-loans \
--target=staging-settings \
--non-interactive \
--trigger-index=0

This simulates a single cron trigger of the matching engine. The workflow will:

  1. Call expireProposals on the GHOST server
  2. Fetch pending intents
  3. Decrypt rates (using the test private key from config)
  4. Run matching
  5. Post proposals back to the server

Execute Transfers

cre workflow simulate ./execute-transfers \
--target=staging-settings \
--non-interactive \
--trigger-index=0

Check Loans

cre workflow simulate ./check-loans \
--target=staging-settings \
--non-interactive \
--trigger-index=0

Configuration for Simulation

Each workflow's config.staging.json should point to your local server for simulation:

{
"schedule": "every 30 seconds",
"ghostApiUrl": "http://localhost:3000",
"internalApiKey": "your-local-api-key"
}

DON secrets are resolved differently in simulation mode. The CRE CLI reads them from local environment variables or a .secrets file rather than the DON's secret store.

Simulation vs Production

AspectSimulationProduction
Execution environmentLocal Node.js/WASMDON TEE nodes
Secret managementLocal env vars / .secrets fileDON threshold secret store
HTTP clientDirect fetchConfidentialHTTPClient (encrypted)
EVM readsDirect RPCEVMClient through DON
TriggerManual (CLI)Cron schedule
ConsensusSingle executionThreshold consensus across DON nodes

WASM Compatibility Notes

When developing CRE workflows, be aware of WASM constraints:

Compatible libraries:

  • eciesjs v0.4 (pure JS/WASM ECIES)
  • viem v2 (Ethereum utilities)
  • @noble/hashes (cryptographic hashes)
  • ethers v6 (wallet signing, ABI encoding)

Not compatible:

  • Node.js built in modules (fs, crypto, net, path)
  • Native addons (anything requiring node-gyp)
  • Libraries that use process.env directly (use config instead)

Import Rules

All CRE SDK imports must come from the root package:

// Correct
import { ConfidentialHTTPClient, EVMClient } from "@chainlink/cre-sdk";

// Incorrect (will fail in WASM)
import { ConfidentialHTTPClient } from "@chainlink/cre-sdk/http";

HTTP Request Pattern

The CRE SDK uses a builder pattern for HTTP requests:

const response = ConfidentialHTTPClient.sendRequest(runtime, {
url: "https://example.com/api",
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": config.apiKey,
},
body: JSON.stringify(payload),
}).result();

const data = JSON.parse(response.body);

Note the .result() call at the end. This is required to execute the request and retrieve the response synchronously within the WASM runtime.

Workflow Handler Signature

Every CRE workflow exports a handler with this signature:

import type { Runtime, CronPayload } from "@chainlink/cre-sdk";

interface Config {
schedule: string;
ghostApiUrl: string;
internalApiKey: string;
// ... workflow-specific config
}

export default function handler(
runtime: Runtime<Config>,
payload: CronPayload
): string {
// Workflow logic here
return "Execution summary";
}

The handler receives the runtime (with config and SDK access) and the cron payload (trigger metadata). It must return a string that is logged by the DON.

Debugging Tips

ProblemSolution
"Module not found" in WASMCheck that the dependency is WASM compatible and imported from root
ConfidentialHTTPClient returns emptyCheck that .result() is called on the request
Secrets not resolvingIn simulation, set them as env vars or in .secrets
EVMClient read failsVerify RPC URL and contract address in config
Timeout during simulationIncrease CLI timeout with --timeout=60000