Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

delay

Pause the run for a duration, durably.

rflow_version: 1
name: pay-then-verify
 
config:
  port: 3940
  db_connection: ${DATABASE_URL}
 
networks:
  - name: ethereum
    chain_id: 1
    rpc: ${ETH_RPC}
 
signer:
  raw:
    mnemonic: ${RAW_DANGEROUS_MNEMONIC}
 
relayers:
  payout:
    networks: [ethereum]
 
contracts:
  Token:
    abi: ./abis/erc20.json
    network: ethereum
    address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
 
workflows:
  pay-then-verify:
    trigger:
      event:
        contract: Token
        name: Transfer
        network: ethereum
    steps:
      - id: submit
        send_transaction:
          network: ethereum
          relayer: payout
          contract: Token
          function: "transfer(address,uint256)"
          args: ["${{ trigger.args.from }}", "${{ trigger.args.value }}"]
      - delay: 30s
      - id: verify
        read:
          contract: Token
          network: ethereum
          function: "balanceOf(address)"
          args: ["${{ trigger.args.from }}"]

The action is just the duration string: 30s, 5m, 2h, 1d.

Durable means durable

delay is not a sleep. The wake-at timestamp is persisted to the journal (waiting_delay state) before the wait starts, so:

  • a restart or crash mid-delay resumes the countdown against the persisted wake time; it neither resets nor skips
  • a delay that elapsed while the process was down fires immediately on recovery
  • long delays (hours, days) are safe and cost nothing while parked

When to use it

  • settling time between a send and a verification read
  • pacing between actions to a rate-limited API
  • fixed "wait then check" patterns. When you are waiting for a specific onchain event rather than a duration, use the wait_for: step instead (it races events against a timeout)