Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/content/cre/guides/operations/custom-build.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "Custom WASM Builds"
metadata:
description: "Learn how to take ownership of the WASM build step in CRE workflows using cre workflow custom-build and a custom Makefile."
datePublished: "2026-02-26"
lastModified: "2026-02-26"
lastModified: "2026-10-30"
---

import { Aside } from "@components"
Expand Down Expand Up @@ -116,6 +116,19 @@ When `make build` runs you'll see `Running my custom build step...` printed befo

Swap the `echo` for any real step: type checking, linting, code generation, or a custom compiler invocation.

## Build once without converting your workflow

If you only need to compile once and reuse the binary, for example to run many simulations against the same build, you don't have to convert your workflow. Build the binary with `cre workflow build`, then pass it with `--wasm`:

```bash
cre workflow build ./my-workflow
cre workflow simulate ./my-workflow --wasm ./binary.wasm --target staging-settings
```

This leaves your `workflow.yaml` unchanged, so you can still let the CLI compile your source at any time. The `--wasm` flag is available on [`cre workflow simulate`](/cre/reference/cli/workflow#cre-workflow-simulate), [`cre workflow hash`](/cre/reference/cli/workflow#cre-workflow-hash), and [`cre workflow deploy`](/cre/reference/cli/workflow#cre-workflow-deploy). For details on how `simulate` resolves the path, see [Simulating with a pre-built binary](/cre/guides/operations/simulating-workflows#simulating-with-a-pre-built-binary).

Choose `custom-build` when you need to change how the binary is compiled. Choose `build` with `--wasm` when you only need to compile once.

## Generated Makefile

The generated `Makefile` is ready to use. The only requirement is that `make build` produces `wasm/workflow.wasm`.
Expand Down
61 changes: 57 additions & 4 deletions src/content/cre/guides/operations/simulating-workflows.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "Simulating Workflows"
metadata:
description: "Simulate your workflows: learn to simulate CRE workflows with real API and testnet calls before deploying them."
datePublished: "2025-11-04"
lastModified: "2026-10-19"
lastModified: "2026-10-30"
---

import { Aside, CopyText } from "@components"
Expand Down Expand Up @@ -39,7 +39,7 @@ cre workflow simulate my-workflow --target staging-settings

### What happens during simulation

1. **Compilation**: The CLI compiles your workflow to WebAssembly (WASM).
1. **Compilation**: The CLI compiles your workflow to WebAssembly (WASM). If you pass a pre-built binary with `--wasm`, the CLI skips this step. See [Simulating with a pre-built binary](#simulating-with-a-pre-built-binary).
1. **Trigger selection**: You're prompted to select which trigger to test (cron, HTTP, EVM log, or Solana log).
1. **Execution**: The workflow runs locally, making real calls to configured RPCs and HTTP endpoints.
1. **Output**: The simulator displays logs from your workflow and the final execution result.
Expand Down Expand Up @@ -116,14 +116,67 @@ cre workflow simulate my-workflow --non-interactive --trigger-index 0 --target s

The `--listen` flag keeps the simulator alive and re-runs it for each incoming trigger event, instead of compiling and executing once then exiting.

- **HTTP triggers**: starts a local HTTP server on port `2000`. Each POST request triggers a fresh simulation run.
- **HTTP triggers**: starts a local HTTP server on port `2000` (change it with `--http-trigger-port`). Each POST request to `/trigger` triggers a simulation run.
- **EVM log triggers**: watches the configured chain and re-runs on each matching log event.

```bash
cre workflow simulate my-workflow --listen --target staging-settings
```

This is useful during active development — make a code change, resave, send another event, and see the result immediately without restarting the CLI. See [Testing HTTP Triggers in Simulation](/cre/guides/workflow/using-triggers/http-trigger/testing-in-simulation) for a detailed walkthrough with HTTP triggers.
This is useful when you want to send many test events without restarting the CLI. The simulator compiles your workflow once, when it starts, so restart it after you change your workflow code.

### How listen mode handles HTTP requests

Keep the following behavior in mind when you send requests to the local HTTP server:

- **Request format**: Send a `POST` request to `http://localhost:2000/trigger` with a JSON body of the form `{"input": { ... }}`. The simulator passes the value of `input` to your workflow as the trigger payload. Other body shapes, such as a gateway `workflows.execute` request, are not unwrapped. If `input` is missing, your workflow runs with an empty payload.
- **Response**: The server returns an empty `200 OK` as soon as it accepts the request, before the workflow runs. Logs and the workflow result appear in the terminal where the simulator is running, not in the HTTP response. A body that isn't valid JSON returns `400 Bad Request` and does not start a run.
- **One run at a time**: The simulator runs requests in order. It holds up to 16 pending requests and returns `429 Too Many Requests` after that.
- **Rate limit**: By default, the simulator enforces the production HTTP trigger [service quota](/cre/service-quotas#http-trigger): one run per 30 seconds. The simulator skips requests that arrive sooner, prints `Trigger rate limited, skipping execution` in the terminal, and still returns `200 OK` to the caller. To send requests more often, run with `--limits none`. See [Testing Production Limits](/cre/guides/operations/understanding-limits).
- **Errors**: If your workflow returns an error, the simulator logs it and keeps listening. Errors raised by the simulation engine itself, such as exceeding a resource limit, end the session.
- **One workflow per simulator**: Each `--listen` process serves a single workflow and trigger. To serve several workflows locally, start one simulator per workflow, each with its own `--http-trigger-port`.

<Aside type="note" title="Using --listen with --non-interactive">
If you combine `--listen` with `--non-interactive` for an HTTP trigger, you must also pass `--http-payload`. The
simulator runs that payload first, then keeps listening for more requests.
</Aside>

See [Testing HTTP Triggers in Simulation](/cre/guides/workflow/using-triggers/http-trigger/testing-in-simulation) for a detailed walkthrough with HTTP triggers, including how the local server differs from the deployed gateway.

## Simulating with a pre-built binary

By default, each `cre workflow simulate` run compiles your workflow to WASM. If you build the binary once and simulate it many times, for example in a CI/CD pipeline or from a script that starts several simulations, you can skip compilation.

There are two ways to do this:

- **`--wasm` flag**: Build the binary with [`cre workflow build`](/cre/reference/cli/workflow#cre-workflow-build), then pass it to `simulate`. Your `workflow.yaml` stays unchanged.
- **Custom build**: Convert the workflow with [`cre workflow custom-build`](/cre/guides/operations/custom-build). The CLI then runs the binary at `wasm/workflow.wasm` that your `Makefile` produces. This changes your `workflow.yaml` permanently.

**Example using `--wasm`:**

```bash
# Build once. The binary is written to ./my-workflow/binary.wasm by default
cre workflow build ./my-workflow --target staging-settings

# Simulate the pre-built binary as many times as you like
cre workflow simulate ./my-workflow --wasm ./binary.wasm --target staging-settings
```

When you pass `--wasm`:

- The simulator runs the binary as-is and does not read your workflow source. If you change your code, rebuild the binary.
- The simulator still reads your `workflow.yaml` for the config and secrets paths, and the target settings.
- You can start several simulations at the same time against the same binary. They don't write build output, so they don't overwrite each other.
- A relative path is resolved from the workflow directory, not from where you ran the command. In the example above, `./binary.wasm` points to `./my-workflow/binary.wasm`.
- A local path can be at most 97 characters. If your path is longer, use a shorter location or a relative path.
- The value can also be a URL, which the CLI downloads before it simulates.

<Aside type="tip" title="Same binary for simulate, hash, and deploy">
The `--wasm` flag is also available on [`cre workflow hash`](/cre/reference/cli/workflow#cre-workflow-hash) and [`cre
workflow deploy`](/cre/reference/cli/workflow#cre-workflow-deploy). Building once and passing the same binary to each
command ensures you simulate the exact artifact you deploy. The binary hash printed during simulation matches the hash
printed by `cre workflow build`.
</Aside>

## The `--broadcast` flag

Expand Down
12 changes: 11 additions & 1 deletion src/content/cre/guides/operations/understanding-limits.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "Testing Production Limits"
metadata:
description: "Test workflows against production limits locally: use the --limits flag to enforce, disable, or customize simulation limits before deploying."
datePublished: "2026-03-19"
lastModified: "2026-03-19"
lastModified: "2026-10-30"
---

import { Aside, CodeSample } from "@components"
Expand Down Expand Up @@ -61,6 +61,16 @@ cre workflow simulate my-workflow --limits ./my-limits.json --target staging-set

See [Customizing limits](#customizing-limits) for how to create a custom limits file.

### Limits in listen mode

Simulation limits apply to every run in [listen mode](/cre/guides/operations/simulating-workflows#listen-mode). The default HTTP trigger quota allows one run per 30 seconds, so the simulator skips HTTP requests that arrive sooner. The simulator prints `Trigger rate limited, skipping execution` in the terminal, but the HTTP response is still `200 OK`. To send requests more often while you develop, run with `--limits none`:

```bash
cre workflow simulate my-workflow --listen --limits none --target staging-settings
```

See the [HTTP trigger quota](/cre/service-quotas#http-trigger) for the production value.

## Viewing default limits

Use the [`cre workflow limits export`](/cre/reference/cli/workflow#cre-workflow-limits) command to inspect the default production limits:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ date: Last Modified
metadata:
description: "Test deployed HTTP trigger workflows easily with the cre-http-trigger TypeScript tool: automatic JWT generation, local proxy server, and simple configuration."
datePublished: "2025-11-04"
lastModified: "2026-01-14"
lastModified: "2026-10-30"
---

import { Aside } from "@components"
Expand All @@ -26,6 +26,12 @@ The `cre-http-trigger` tool eliminates this complexity by:
JWT generation directly in your backend service for better security and control.
</Aside>

<Aside type="note" title="Looking to test without deploying?">
This tool sends requests to a **deployed** workflow through the gateway. To test an HTTP trigger locally before you
deploy, use [`cre workflow simulate`](/cre/guides/workflow/using-triggers/http-trigger/testing-in-simulation). Both
listen on `localhost:2000/trigger` by default, but they do different things.
</Aside>

{/* prettier-ignore */}
<Aside type="caution" title="Educational Example Disclaimer">
This page includes an educational example to use a Chainlink system, product, or service and is provided to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ date: Last Modified
metadata:
description: "Test HTTP triggers locally with the CRE simulator: provide JSON payloads interactively or via command-line flags for rapid development."
datePublished: "2025-11-10"
lastModified: "2026-06-11"
lastModified: "2026-10-30"
---

import { Aside, CodeHighlightBlockMulti } from "@components"
Expand Down Expand Up @@ -47,21 +47,36 @@ The simulator will detect your HTTP trigger and prompt you to select it from ava

## Listen mode

Use `--listen` to keep the simulator alive between runs. Instead of simulating once and exiting, the CLI starts a local HTTP server on port `2000` and re-runs the simulator every time it receives a POST request — no need to restart between tests.
Use `--listen` to keep the simulator alive between runs. Instead of simulating once and exiting, the CLI starts a local HTTP server on port `2000` and re-runs the simulator every time it receives a POST request — no need to restart between test payloads.

```bash
cre workflow simulate my-http-workflow --listen --target staging-settings
```

Once running, send payloads with any HTTP client:
Once running, send payloads to `/trigger` with any HTTP client. Wrap your payload in an `input` field:

```bash
curl -X POST http://localhost:2000 \
curl -X POST http://localhost:2000/trigger \
-H "Content-Type: application/json" \
-d '{"userId":"123","action":"purchase","amount":100}'
-d '{"input":{"userId":"123","action":"purchase","amount":100}}'
```

Each POST triggers a fresh simulation run. Press `Ctrl+C` to stop.
Your workflow receives the value of `input` as the trigger payload. Each POST triggers a simulation run. Press `Ctrl+C` to stop.

<Aside type="note" title="Restart to pick up code changes">
The simulator compiles your workflow once, when it starts. If you change your workflow code, restart the simulator. To
avoid recompiling on every start, see [Simulating with a pre-built
binary](/cre/guides/operations/simulating-workflows#simulating-with-a-pre-built-binary).
</Aside>

<Aside type="caution" title="Default limits skip requests sent less than 30 seconds apart">
By default, the simulator enforces the production [HTTP trigger quota](/cre/service-quotas#http-trigger): one run per
30 seconds. In listen mode, the simulator skips requests that arrive sooner and still returns `200 OK`. The only sign
is a `Trigger rate limited, skipping execution` message in the terminal. To send requests more often, add `--limits
none`. See [Testing Production Limits](/cre/guides/operations/understanding-limits).
</Aside>

For the full list of listen mode behavior, including queuing and error handling, see [Listen mode](/cre/guides/operations/simulating-workflows#listen-mode).

## Providing input data

Expand Down Expand Up @@ -269,6 +284,30 @@ This helps you verify error handling and edge cases before deployment.
The CLI will reject deployments with HTTP triggers that lack authorization configuration.
</Aside>

## Local listener vs the deployed gateway

If your backend triggers deployed workflows through the CRE gateway, you may want to send the same requests to the local simulator. The local HTTP server that `--listen` starts is not a copy of the gateway. Use this table to see what differs:

| Aspect | Local simulator (`--listen`) | Deployed workflow (gateway) |
| ---------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Endpoint** | `POST http://localhost:2000/trigger` | The [gateway URL](/cre/guides/workflow/using-triggers/http-trigger/triggering-deployed-workflows#gateway-urls) for your workflow's DON |
| **Request format** | `{"input": { ... }}` | JSON-RPC `workflows.execute` request with the payload in `params.input`. See [Request format](/cre/guides/workflow/using-triggers/http-trigger/triggering-deployed-workflows#request-format) |
| **Workflow selection** | One workflow and trigger per simulator process. The request does not choose a workflow | The request selects the workflow, for example with `params.workflow.workflowID` |
| **Authorization** | None. The simulator does not check a JWT or `authorizedKeys` | JWT signed with a key listed in `authorizedKeys`. See [JWT authentication](/cre/guides/workflow/using-triggers/http-trigger/triggering-deployed-workflows#jwt-authentication) |
| **Response** | Empty `200 OK`, returned before the workflow runs. Results appear in the terminal | JSON-RPC response with `result.status` set to `ACCEPTED`. See [Response format](/cre/guides/workflow/using-triggers/http-trigger/triggering-deployed-workflows#response-format) |
| **Execution** | One run at a time. Up to 16 requests wait in a queue | Asynchronous on the DON |
| **Rate limit** | One run per 30 seconds by default. Skipped requests still return `200 OK`. Disable with `--limits none` | Production [HTTP trigger quota](/cre/service-quotas#http-trigger) |
| **Invalid requests** | `400 Bad Request` if the body isn't valid JSON. If `input` is missing, the workflow runs with an empty payload | JSON-RPC error response. See [Error response](/cre/guides/workflow/using-triggers/http-trigger/triggering-deployed-workflows#error-response) |

To send gateway-format requests to the simulator, unwrap `params.input` in your own code and send it as `{"input": ...}` to `/trigger`. To run several workflows locally, start one simulator per workflow, each with its own `--http-trigger-port`. To test JWT authorization, use a deployed workflow. See [Testing with Local JWT Server](/cre/guides/workflow/using-triggers/http-trigger/local-testing-tool).

<Aside type="note" title="Two tools can use port 2000">
The `cre-http-trigger` tool in [Testing with Local JWT
Server](/cre/guides/workflow/using-triggers/http-trigger/local-testing-tool) also listens on `localhost:2000/trigger`,
but it forwards your request to a deployed workflow. It does not run the simulator. If you run both at the same time,
start the simulator on another port with `--http-trigger-port`.
</Aside>

## Next steps

Once you've tested your workflow locally:
Expand Down
Loading
Loading