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

signer

The signing provider: the key material your relayers derive wallets from. Exact rrelayer signing_providers schema, all 9 providers. Optional: monitoring-only projects declare no signer and the relayer engine never boots.

Exactly one provider must be set (validation error otherwise).

rflow_version: 1
name: price-keeper
 
config:
  port: 3940
  db_connection: ${DATABASE_URL}
 
signer: 
  aws_kms: 
    region: eu-west-1
 
networks:
  - name: ethereum
    chain_id: 1
    rpc: ${ETH_RPC}
 
# the relayers derive their wallets from the signer above
relayers:
  keeper:
    networks: [ethereum]
 
workflows:
  price-keeper:
    trigger:
      interval:
        every: 30s
    steps:
      - id: poke
        send_transaction:
          network: ethereum
          relayer: keeper
          to: "0xOracle..."
          function: "poke()"

Each provider block below drops into that same top-level signer: slot.

The 9 providers

Field-level semantics are rrelayer's; see the rrelayer signing provider docs for provider setup guides.

raw β€” dev only

signer:
  raw:
    mnemonic: ${RAW_DANGEROUS_MNEMONIC}

A plain mnemonic. Fine for anvil and testnets; the env var name says the rest.

private_keys

signer:
  private_keys: [${PK_0}, ${PK_1}]

aws_kms

signer:
  aws_kms:
    region: eu-west-1
    # endpoint_url, multi_region, danger_override_alias β€” optional

aws_secret_manager

signer:
  aws_secret_manager: { id: my-secret, key: mnemonic, region: eu-west-1 }

gcp_secret_manager

signer:
  gcp_secret_manager:
    id: my-secret
    key: mnemonic
    service_account_key_path: ./gcp-sa.json
    # version β€” optional

privy

signer:
  privy: { app_id: ${PRIVY_APP_ID}, app_secret: ${PRIVY_APP_SECRET} }

turnkey

signer:
  turnkey:
    api_public_key: ${TURNKEY_PUB}
    api_private_key: ${TURNKEY_PRIV}
    organization_id: ${TURNKEY_ORG}
    wallet_id: ${TURNKEY_WALLET}

fireblocks

signer:
  fireblocks:
    api_key: ${FIREBLOCKS_API_KEY}
    private_key_path: ./fireblocks.pem
    identity: my-vault
    # sandbox, hidden_on_ui β€” optional

pkcs11 β€” hardware modules (beta)

signer:
  pkcs11:
    library_path: /usr/lib/softhsm/libsofthsm2.so
    identity: rflow
    # pin, slot_id, test_mode β€” optional

Per-network override

Any network can override the global signer, e.g. KMS on mainnet and a raw mnemonic on a testnet:

rflow_version: 1
name: keeper-both-nets
 
config:
  port: 3940
  db_connection: ${DATABASE_URL}
 
signer: 
  aws_kms: { region: eu-west-1 } 
 
networks:
  - name: ethereum
    chain_id: 1
    rpc: ${ETH_RPC}
  - name: sepolia
    chain_id: 11155111
    rpc: ${SEPOLIA_RPC}
    signing_provider: 
      raw: { mnemonic: ${TEST_MNEMONIC} } 
 
relayers:
  mainnet-keeper:
    networks: [ethereum]
  testnet-keeper:
    networks: [sepolia]
 
workflows:
  poke-testnet:
    trigger:
      interval:
        every: 1m
    steps:
      - id: poke
        send_transaction:
          network: sepolia
          relayer: testnet-keeper
          to: "0xOracle..."
          function: "poke()"

How keys map to relayers

One signing provider yields many wallets by wallet index (mnemonic index 0, 1, 2… / KMS key n). When rflow creates a relayer, rrelayer assigns the next free index and persists it; that index is the name↔key mapping. See the relayer lifecycle.