Relayer

Configuration

Overview

Most configuration files should live under ./config, including the signer configurations, under ./config/keys. Please ensure appropriate access permissions on all configuration files (for ./config/keys/*, we recommend 0500.

The OpenZeppelin Relayer supports two configuration approaches:

File-based Configuration:

  1. config.json: Contains relayer definitions, signer configurations, and network policies
  2. .env file: Contains environment variables like API keys and connection strings

API-based Configuration:

  • Full CRUD operations for relayers, signers, and notifications via REST API
  • Changes take effect immediately (no container restart required)
  • See the API Reference page for detailed endpoints documentation

See Storage Configuration for detailed information about how file-based and API-based configurations work together, storage behavior, and best practices.

For quick setup examples with pre-configured files, see the examples directory in our GitHub repository.

Environment configuration (.env)

This defines some base configurations for the Relayer application:

Copy the example environment file and update values according to your needs

cp .env.example .env

This table lists the environment variables and their default values.

Environment VariableDefault ValueAccepted ValuesDescription
RUST_LOGinfoinfo, debug, warn, error, traceLog level.
REPOSITORY_STORAGE_TYPEin-memoryin-memory, redisType of storage used for storing repository config and resources. See Storage Configuration for detailed information.
RESET_STORAGE_ON_STARTfalseboolClears all resources from storage on startup and reloads entries from the config file. See Storage Configuration for usage details.
TRANSACTION_EXPIRATION_HOURS4numberNumber of hours after which transactions in a final state are removed from storage. See Storage Configuration for more information.
CONFIG_DIR./config<any relative file path where config.json is located>Relative path of directory where config files reside
CONFIG_FILE_NAMEconfig.json<any file name>File Name of the configuration file.
RATE_LIMIT_RPS100<any value>Rate limit for the API in requests per second.
RATE_LIMIT_BURST_SIZE300<any value>Rate limit burst size.
API_KEY``string,API key to use for authentication to the relayer server. Minimum length 32 characters.
WEBHOOK_SIGNING_KEY``stringSigning key to use for webhook notifications. Minimum length 32 characters.
LOG_MODEstdoutstdout, fileWrite logs either to console or to file.
LOG_DATA_DIR./logs<any file path>Directory to persist log files on host.
LOG_MAX_SIZE (in bytes)1073741824<any value in bytes>Size after which logs needs to be rolled.
METRICS_ENABLEDfalseboolEnable metrics server for external tools to scrape metrics.
METRICS_PORT8081<any tcp port (preferably choose non-privileged ports i.e. (1024-65535))>Port to use for metrics server.
REDIS_URLredis://localhost:6379<redis connection string>Redis connection URL for the relayer. See Storage Configuration for Redis setup details.
REDIS_CONNECTION_TIMEOUT_MS10000<timeout in milliseconds>Connection timeout for Redis in milliseconds. See Storage Configuration for Redis configuration.
REDIS_KEY_PREFIXoz-relayerstringRedis key prefix for namespacing. See Storage Configuration for more information.
STORAGE_ENCRYPTION_KEY``stringEncryption key used to encrypt data at rest in Redis storage. See Storage Configuration for security details.
RPC_TIMEOUT_MS10000<timeout in milliseconds>Sets the maximum time to wait for RPC connections before timing out.
PROVIDER_MAX_RETRIES3<number of retries>Maximum number of retry attempts for provider operations.
PROVIDER_RETRY_BASE_DELAY_MS100<delay in milliseconds>Base delay between retry attempts in milliseconds.
PROVIDER_RETRY_MAX_DELAY_MS2000<delay in milliseconds>Maximum delay between retry attempts in milliseconds.
PROVIDER_MAX_FAILOVERS3<number of failovers>Maximum number of failovers (switching to different providers).
ENABLE_SWAGGERfalsetrue, falseEnable or disable Swagger UI for API documentation.
KEYSTORE_PASSPHRASE``<keystore passphrase>Passphrase for the keystore file used for signing transactions.

Environment configuration example

.env file config example:

RUST_LOG=DEBUG
CONFIG_DIR=./config
CONFIG_FILE_NAME=config.json
WEBHOOK_SIGNING_KEY=e1d42480-6f74-4d0b-85f4-b7f0bb690fae
API_KEY=5eefd216-0e44-4ca7-b421-2925f90d30d5
RATE_LIMIT_RPS=100
RATE_LIMIT_BURST_SIZE=300
METRICS_ENABLED=true
METRICS_PORT=8081
REDIS_URL=redis://localhost:6379
REDIS_CONNECTION_TIMEOUT_MS=10000
REDIS_KEY_PREFIX=oz-relayer
RPC_TIMEOUT_MS=10000
PROVIDER_MAX_RETRIES=3
PROVIDER_RETRY_BASE_DELAY_MS=100
PROVIDER_RETRY_MAX_DELAY_MS=2000
PROVIDER_MAX_FAILOVERS=3
ENABLE_SWAGGER=false
KEYSTORE_PASSPHRASE=your_keystore_passphrase
STORAGE_ENCRYPTION_KEY=X67aXacJB+krEldv9i2w7NCSFwwOzVV/1ELM2KJJjQw=
REPOSITORY_STORAGE_TYPE=redis
RESET_STORAGE_ON_START=false
TRANSACTION_EXPIRATION_HOURS=8

Main configuration file (config.json)

This file can exist in any directory, but the default location is ./config/config.json.

All components defined in config.json can also be managed via REST API endpoints. This provides runtime flexibility for adding, updating, or removing relayers, signers, and notifications without restarting the service. See the API Reference page for detailed endpoints documentation.

Key sections in this file include:

  • Signers: Defines transaction signing methods.
  • Notifications: Sets up status alerts
  • Relayers: Configures networks, notifications channels, policies & singers.
  • Networks: Defines blockchain network configurations.
  • Plugins: Configures plugins.

1. Signers

Transaction signers are responsible for cryptographically signing transactions before they are submitted to blockchain networks.

For comprehensive details on configuring all supported signer types including:

  • Local keystore file signers
  • HashiCorp Vault (secret and transit)
  • Cloud KMS providers (Google Cloud, AWS)
  • Turnkey signers
  • Security best practices and troubleshooting

See the dedicated Signers Configuration guide.

Signers can also be managed via API endpoints.

See the API Reference page for detailed endpoints documentation.

2. Notifications

  • notifications array containing notification entries:
"notifications": [

    "id": "notification-test",
    "type": "webhook",
    "url": "https://webhook.site/f95cf78d-742d-4b21-88b7-d683e6fd147b",
    "signing_key": {
      "type": "env",
      "value": "WEBHOOK_SIGNING_KEY"

  }
]

Available configuration fields

FieldTypeDescription
idStringUnique id for the notification
typeStringType of notification (only webhook available, for now)
urlStringNotification URL
signing_key.typeStringType of key used in signing the notification (env or plain)
signing_key.valueStringSigning key value, env variable name, ...

Notifications can also be managed via API endpoints.

See the API Reference page for detailed endpoints documentation.

3. Relayers

  • relayers array, containing relayer entries:
"relayers": [

    "id": "solana-testnet",
    "name": "Solana Testnet",
    "paused": false,
    "notification_id": "notification-test",
    "signer_id": "local-signer",
    "network_type": "solana",
    "network": "testnet",
    "custom_rpc_urls": [
      {
        "url": "https://primary-rpc.example.com",
        "weight": 2  // Higher weight routes more requests to this endpoint. The value must be an integer between 0 and 100 (inclusive).
      ,

        "url": "https://backup-rpc.example.com",
        "weight": 1

    ],
    "policies":
      "allowed_programs": [
          "11111111111111111111111111111111",
          "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
          "BPFLoaderUpgradeab1e11111111111111111111111"
        ]

  }
]

Available configuration fields

FieldTypeDescription
idStringUnique id for the relayer
nameStringHuman readable name for the relayer
pausedBooleanWhether or not the relayer is paused (true, false)
notification_idStringID of a configured notification object
signer_idStringID of a configured signer
network_typeStringType of network the relayer will connect to (evm, solana)
networkStringNetwork the relayer will connect to. Must match a network identifier defined in your network configuration files. See Network Configuration for details on defining networks.
custom_rpc_urlslistOptional custom RPC URLs for the network. If provided, this will be used instead of the public RPC URLs. This is useful for using your own RPC node or a paid service provider. The first url of the list is going to be used as the default
policieslistOverrides default policies. Please refer to the Policies table

Policies

Network typePolicyTypeDescription
solana, evmmin_balanceunsigned 128Minimum balance (in lamports or wei) required for the relayer to operate. Optional.
solanafee_payment_strategyenum(user,relayer)Specifies who pays the fee. "user" (default) means the sender pays; "relayer" means the relayer pays. For "user", RPC methods add an instruction to transfer SPL tokens (calculated from the current SOL price plus a configurable margin) from the user to the relayer, ensuring fees are sustainably covered in tokens rather than SOL.
solanaswap_configSwapConfigOptional object configuring automated token‐swaps on Solana.
solanafee_margin_percentagef32Additional margin percentage added to estimated transaction fees to account for price fluctuations. For example, a value of 10 will add 10% to estimated fees. Optional.
solanamax_allowed_fee_lamportsunsigned 64Maximum allowed fee (in lamports) for a transaction. Optional.
solanaallowed_tokensVector<AllowedToken>List of allowed tokens. Only these tokens are supported if provided. Optional.
solanaallowed_programsVector<String>List of allowed programs by their identifiers. Only these programs are supported if provided. Optional.
solanaallowed_accountsVector<String>List of allowed accounts by their public keys. The relayer will only operate with these accounts if provided.
solanadisallowed_accountsVector<String>List of disallowed accounts by their public keys. These accounts will be explicitly blocked.
solanamax_tx_data_sizeunsigned 16Maximum transaction size. Optional.
solanamax_signaturesunsigned 8Maximum supported signatures. Optional.
evmgas_price_capunsigned 128Specify a maximum gas price for every transaction sent with the Relayer. When enabled, any transaction exceeding the cap will have its gasPrice or maxFeePerGas overwritten. (Optional)
evmgas_limit_estimationboolAutomatic gas_limit calculation. Enabled by default. (Optional)
evmwhitelist_receiversVector<String>A list of authorized contracts for each transaction sent using the Relayer. Transactions will be rejected if the destination address is not on the list. (Optional)

RPC URL Configuration

The relayer supports two ways to configure RPC URLs:

  1. Public RPC URLs: These are the default RPC endpoints provided by the network. They are automatically selected based on the network configuration.
  2. Custom RPC URLs: You can specify custom RPC URLs using the custom_rpc_urls field in the relayer configuration. Each URL can be configured with an optional weight for high availability:
"custom_rpc_urls": [

    "url": "https://primary-rpc.example.com",
    "weight": 2  // Higher weight routes more requests to this endpoint. The value must be an integer between 0 and 100 (inclusive).
  ,

    "url": "https://secondary-rpc.example.com",
    "weight": 100, // Max allowed weight
  ,

    "url": "https://backup-rpc.example.com"  // No weight specified, defaults to 100
  ,

    "url": "https://backup2-rpc.example.com",
    "weight": 0, //  A value of 0 disables the endpoint.

]

This is useful when you want to:

  • Use your own RPC nodes with load balancing
  • Use a paid service provider for better reliability and performance
  • Override the default public RPC URLs
  • Access custom network endpoints
  • Configure primary and backup endpoints with different weights

When both are available, the relayer will:

  1. First attempt to use the custom_rpc_urls if configured.
  2. Fall back to the public RPC URLs if no custom URL is configured.

For backward compatibility, string arrays are still supported:

"custom_rpc_urls": ["https://your-rpc.example.com"]

When using custom RPC URLs:

  • Ensure the URLs are secure (HTTPS) when accessing over public networks
  • Keep your API keys and authentication tokens secure
  • Test the RPC endpoints' reliability and performance before using it in production
  • Configure weights to prioritize endpoints, assigning higher values to more reliable or performant ones.
  • The weight must be an integer between 0 and 100 (inclusive).
  • A weight of 0 disables the endpoint.
  • If a weight is not specified for an endpoint, it defaults to 100.

Relayers could also be managed via API endpoints.

See the API Reference page for detailed endpoints documentation.

4. Plugins

For more information on how to write a plugin, please refer to the Plugins page.

  • plugins array, containing plugin configurations:
"plugins": [

    "id": "my-plugin",
    "path": "my-plugin.ts"

]

Available configuration fields

FieldTypeDescription
idStringUnique id for the plugin
pathStringPath to the plugin file

5. Networks

You can configure networks either:

  • In separate JSON files (recommended for better organization)
  • Directly in your main config.json

For comprehensive network configuration details, including:

  • Network field reference
  • Configuration examples for all network types
  • Network inheritance
  • Special tags and their behavior
  • Best practices and troubleshooting

See the dedicated Network Configuration guide.

Configuration File Example

Full config/config.json example with evm and solana relayers definitions using keystore signer:


  "relayers": [
    {
      "id": "sepolia-example",
      "name": "Sepolia Example",
      "network": "sepolia",
      "paused": false,
      "notification_id": "notification-example",
      "signer_id": "local-signer",
      "network_type": "evm",
      "custom_rpc_urls": [
        {
          "url": "https://primary-rpc.example.com",
          "weight": 2
        ,

          "url": "https://backup-rpc.example.com",
          "weight": 1

      ],
      "policies":
        "gas_price_cap": 30000000000000,
        "eip1559_pricing": true

    },

      "id": "solana-example",
      "name": "Solana Example",
      "network": "devnet",
      "paused": false,
      "notification_id": "notification-example",
      "signer_id": "local-signer",
      "network_type": "solana",
      "custom_rpc_urls": [
        {
          "url": "https://primary-solana-rpc.example.com",
          "weight": 2
        ,

          "url": "https://backup-solana-rpc.example.com",
          "weight": 1

      ],
      "policies":
        "fee_payment_strategy": "user",
        "min_balance": 0,
        "allowed_tokens": [
          {
            "mint": "Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr",
            "max_allowed_fee": 100000000
          ,

            "mint": "So11111111111111111111111111111111111111112"

        ]
      }
    },

      "id": "solana-mainnet-example",
      "name": "Solana Mainnet Example",
      "network": "mainnet-beta",
      "paused": false,
      "notification_id": "notification-example",
      "signer_id": "local-signer",
      "network_type": "solana",
      "custom_rpc_urls": ["https://your-private-solana-rpc.example.com"],
      "policies": {
        "fee_payment_strategy": "user",
        "min_balance": 0,
        "swap_config": {
          "cron_schedule": "0 0 * * * *",
          "min_balance_threshold": 0,
          "strategy": "jupiter-ultra"
        ,
        "allowed_tokens": [

            "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
            "max_allowed_fee": 100000000,
            "swap_config": {
              "min_amount": 0,
              "max_amount": 0,
              "retain_min_amount": 0

          },

            "mint": "So11111111111111111111111111111111111111112"

        ]
      }
    }
  ],
  "notifications": [

      "id": "notification-example",
      "type": "webhook",
      "url": "https://webhook.site/1384d4d9-21b1-40a0-bcd1-d3f3b66be955",
      "signing_key": {
        "type": "env",
        "value": "WEBHOOK_SIGNING_KEY"

    }
  ],
  "signers": [

      "id": "local-signer",
      "type": "local",
      "config": {
        "path": "config/keys/local-signer.json",
        "passphrase": {
          "type": "env",
          "value": "KEYSTORE_PASSPHRASE"

      }
    }
  ],
  "networks": [

      "average_blocktime_ms": 12000,
      "chain_id": 11155111,
      "explorer_urls": [
        "https://api-sepolia.etherscan.io/api",
        "https://sepolia.etherscan.io"
      ],
      "features": [
        "eip1559"
      ],
      "is_testnet": true,
      "network": "sepolia",
      "required_confirmations": 6,
      "rpc_urls": [
        "https://sepolia.drpc.org",
        "https://1rpc.io/sepolia",
        "https://ethereum-sepolia-rpc.publicnode.com",
        "https://ethereum-sepolia-public.nodies.app"
      ],
      "symbol": "ETH",
      "tags": [
        "deprecated"
      ],
      "type": "evm"
    ,

      "type": "solana",
      "network": "devnet",
      "rpc_urls": ["https://api.devnet.solana.com"],
      "explorer_urls": ["https://explorer.solana.com?cluster=devnet"],
      "average_blocktime_ms": 400,
      "is_testnet": true
    ,

      "type": "solana",
      "network": "mainnet-beta",
      "rpc_urls": ["https://api.mainnet-beta.solana.com"],
      "explorer_urls": ["https://explorer.solana.com"],
      "average_blocktime_ms": 400,
      "is_testnet": false

  ]
}

Configuration Management Approaches

The OpenZeppelin Relayer supports two complementary approaches for configuration management:

File-based Configuration

  • Ideal for initial setup and deployment
  • Configuration persists across restarts
  • Requires container restart for changes to take effect
  • Suitable for infrastructure-as-code workflows

API-based Configuration

  • Enables runtime configuration changes
  • No service restarts required
  • Perfect for dynamic environments
  • Supports automated configuration management

See Storage Configuration for detailed information about how file-based and API-based configurations work together, storage behavior, and best practices.