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 configuration system consists of two main components:

  1. config.json: Contains relayer definitions, signer configurations, and network policies

  2. .env file: Contains environment variables like API keys and connection strings

Both files must be properly configured before starting the application. Changes to either file require restarting the container to take effect.

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 Variable Default Value Accepted Values Description

RUST_LOG

info

info, debug, warn, error, trace

Log level.

CONFIG_DIR

./config

<any relative file path where config.json is located>

Relative path of directory where config files reside

CONFIG_FILE_NAME

config.json

<any file name>

File Name of the configuration file.

RATE_LIMIT_RPS

100

<any value>

Rate limit for the API in requests per second.

RATE_LIMIT_BURST_SIZE

300

<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

``

string

Signing key to use for webhook notifications. Minimum length 32 characters.

LOG_MODE

stdout

stdout, file

Write 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_ENABLED

false

bool

Enable metrics server for external tools to scrape metrics.

METRICS_PORT

8081

<any tcp port (preferably choose non-privileged ports i.e. (1024-65535))>

Port to use for metrics server.

REDIS_URL

redis://localhost:6379

<redis connection string>

Redis connection URL for the relayer.

REDIS_CONNECTION_TIMEOUT_MS

10000

<timeout in milliseconds>

Connection timeout for Redis in milliseconds.

RPC_TIMEOUT_MS

10000

<timeout in milliseconds>

Sets the maximum time to wait for RPC connections before timing out.

PROVIDER_MAX_RETRIES

3

<number of retries>

Maximum number of retry attempts for provider operations.

PROVIDER_RETRY_BASE_DELAY_MS

100

<delay in milliseconds>

Base delay between retry attempts in milliseconds.

PROVIDER_RETRY_MAX_DELAY_MS

2000

<delay in milliseconds>

Maximum delay between retry attempts in milliseconds.

PROVIDER_MAX_FAILOVERS

3

<number of failovers>

Maximum number of failovers (switching to different providers).

ENABLE_SWAGGER

false

true, false

Enable 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
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

Main configuration file (config.json)

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

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

cp config/config.example.json config/config.json

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. The signers array must contain at least one valid signer configuration.

For comprehensive details on configuring all supported signer types including:

  • Local keystore file signers

  • HashiCorp Vault (secret, cloud, and transit)

  • Cloud KMS providers (Google Cloud, AWS)

  • Turnkey signers

  • Security best practices and troubleshooting

See the dedicated Signers Configuration guide.

2. Notifications

  • notifications array, which should contain, at least, one valid configuration:

"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

Field Type Description

id

String

Unique id for the notification

type

String

Type of notification (only webhook available, for now)

url

String

Notification URL

signing_key.type

String

Type of key used in signing the notification (env or plain)

signing_key.value

String

Signing key value, env variable name, …​

3. Relayers

  • relayers array, containing at least one valid relayer configuration:

"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

Field Type Description

id

String

Unique id for the relayer

name

String

Human readable name for the relayer

paused

Boolean

Whether or not the relayer is paused (true, false)

notification_id

String

ID of a configured notification object

signer_id

String

ID of a configured signer

network_type

String

Type of network the relayer will connect to (evm, solana)

network

String

Network 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_urls

list

Optional 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

policies

list

Overrides default policies. Please refer to the Policies table

Policies

Network type Policy Type Description

solana, evm

min_balance

unsigned 128

Minimum balance (in lamports or wei) required for the relayer to operate. Optional.

solana

fee_payment_strategy

enum(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.

solana

swap_config

SwapConfig

Optional object configuring automated token‐swaps on Solana.

solana

fee_margin_percentage

f32

Additional 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.

solana

max_allowed_fee_lamports

unsigned 64

Maximum allowed fee (in lamports) for a transaction. Optional.

solana

allowed_tokens

Vector<AllowedToken>

List of allowed tokens. Only these tokens are supported if provided. Optional.

solana

allowed_programs

Vector<String>

List of allowed programs by their identifiers. Only these programs are supported if provided.

solana

allowed_accounts

Vector<String>

List of allowed accounts by their public keys. The relayer will only operate with these accounts if provided.

solana

disallowed_accounts

Vector<String>

List of disallowed accounts by their public keys. These accounts will be explicitly blocked.

solana

max_tx_data_size

unsigned 16

Maximum transaction size. Optional.

solana

max_signatures

unsigned 8

Maximum supported signatures. Optional.

evm

gas_price_cap

unsigned 128

Specify 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)

evm

whitelist_receivers

Vector<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.

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

Field Type Description

id

String

Unique id for the plugin

path

String

Path 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
    }
  ]
}