本文档详细介绍了OpenZeppelin Relayer的配置方法,包括环境变量配置文件(.env)和主配置文件(config.json)。主要涵盖了如何配置Relayer应用的基本设置、交易签名器、通知、网络、策略和插件,以及针对以太坊(EVM)和Solana链的具体配置示例,确保Relayer能够安全可靠地运行。
大多数配置文件应该位于 ./config
目录下,包括签名器配置,位于 ./config/keys
目录下。
请确保所有配置文件都有合适的访问权限(对于 ./config/keys/*
,我们建议权限为 0500
)。
配置系统由两个主要组件构成:<br>1. config.json : 包含中继器定义、签名器配置和网络策略<br> <br>2. .env 文件: 包含环境变量,如 API 密钥和连接字符串<br> <br>在启动应用程序之前,必须正确配置这两个文件。更改任何一个文件都需要重启容器才能生效。<br>要查看带有预配置文件的快速设置示例,请参阅我们 GitHub 仓库中的 examples directory。 |
这为中继器应用程序定义了一些基本配置:
复制示例环境变量文件,并根据你的需要更新值
cp .env.example .env
下表列出了环境变量及其默认值。
环境变量 | 默认值 | 接受的值 | 描述 |
---|---|---|---|
RUST_LOG |
info |
info, debug, warn, error, trace |
日志级别。 |
CONFIG_DIR |
./config |
<config.json 所在的任何相对文件路径> |
配置文件所在的目录的相对路径。 |
CONFIG_FILE_NAME |
config.json |
<任何文件名> |
配置文件的文件名。 |
RATE_LIMIT_RPS |
100 |
<任何值> |
API 的速率限制,单位为每秒请求数。 |
RATE_LIMIT_BURST_SIZE |
300 |
<任何值> |
速率限制突发大小。 |
API_KEY |
`` | string |
用于中继器服务器进行身份验证的 API 密钥。最小长度为 32 个字符。 |
WEBHOOK_SIGNING_KEY |
`` | string |
用于 webhook 通知的签名密钥。最小长度为 32 个字符。 |
LOG_MODE |
stdout |
stdout, file |
将日志写入控制台或文件。 |
LOG_DATA_DIR |
./logs |
<任何文件路径> |
在主机上持久化日志文件的目录。 |
LOG_MAX_SIZE (in bytes) |
1073741824 |
<任何字节值> |
日志需要滚动的大小。 |
METRICS_ENABLED |
false |
bool |
启用指标服务器,以供外部工具抓取指标。 |
METRICS_PORT |
8081 |
<任何 TCP 端口(最好选择非特权端口,即 (1024-65535))> |
用于指标服务器的端口。 |
REDIS_URL |
redis://localhost:6379 |
<Redis 连接字符串> |
中继器的 Redis 连接 URL。 |
REDIS_CONNECTION_TIMEOUT_MS |
10000 |
<以毫秒为单位的超时时间> |
Redis 的连接超时时间,以毫秒为单位。 |
RPC_TIMEOUT_MS |
10000 |
<以毫秒为单位的超时时间> |
设置等待 RPC 连接的最长时间,超过此时间将超时。 |
PROVIDER_MAX_RETRIES |
3 |
<重试次数> |
Provider 操作的最大重试次数。 |
PROVIDER_RETRY_BASE_DELAY_MS |
100 |
<以毫秒为单位的延迟> |
重试尝试之间的基本延迟,以毫秒为单位。 |
PROVIDER_RETRY_MAX_DELAY_MS |
2000 |
<以毫秒为单位的延迟> |
重试尝试之间的最大延迟,以毫秒为单位。 |
PROVIDER_MAX_FAILOVERS |
3 |
<故障转移次数> |
最大故障转移次数(切换到不同的 provider)。 |
ENABLE_SWAGGER |
false |
true, false |
启用或禁用 API 文档的 Swagger UI。 |
KEYSTORE_PASSPHRASE |
`` | <keystore 密码> |
用于签署交易的密钥库文件的密码。 |
.env
文件配置示例:
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
此文件可以存在于任何目录中,但默认位置为 ./config/config.json
。
复制示例配置文件,并根据你的需要更新值
cp config/config.example.json config/config.json
此文件中的关键部分包括:
签名器:定义交易签名方法。
通知:设置状态警报
中继器:配置网络、通知渠道、策略和签名器。
网络:定义区块链网络配置。
插件:配置插件。
交易签名器负责在将交易提交到区块链网络之前对其进行加密签名。signers
数组必须包含至少一个有效的签名器配置。
有关配置所有支持的签名器类型的全面详细信息,包括:
本地密钥库文件签名器
HashiCorp Vault(secret、cloud 和 transit)
Cloud KMS providers (Google Cloud, AWS)
Turnkey 签名器
安全最佳实践和故障排除
请参阅专门的 Signers Configuration 指南。
notifications
数组,应包含至少一个有效的配置:"notifications": [\
{\
"id": "notification-test",\
"type": "webhook",\
"url": "https://webhook.site/f95cf78d-742d-4b21-88b7-d683e6fd147b",\
"signing_key": {\
"type": "env",\
"value": "WEBHOOK_SIGNING_KEY"\
}\
}\
]
可用配置字段
字段 | 类型 | 描述 |
---|---|---|
id | String | 通知的唯一 ID |
type | String | 通知类型(目前仅有 webhook 可用) |
url | String | 通知 URL |
signing_key.type | String | 用于签署通知的密钥类型(env 或 plain ) |
signing_key.value | String | 签名密钥值、环境变量名,等等。 |
relayers
数组,包含至少一个有效的中继器配置:"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 // 权重越高,将更多请求路由到此端点。该值必须是介于 0 到 100(含)之间的整数。\
},\
{\
"url": "https://backup-rpc.example.com",\
"weight": 1\
}\
],\
"policies": {\
"allowed_programs": [\
"11111111111111111111111111111111",\
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",\
"BPFLoaderUpgradeab1e11111111111111111111111"\
]\
}\
}\
]
可用配置字段
字段 | 类型 | 描述 |
---|---|---|
id | String | 中继器的唯一 ID |
name | String | 中继器的易读名称 |
paused | Boolean | 中继器是否暂停(true 、false ) |
notification_id | String | 已配置的通知对象的 ID |
signer_id | String | 已配置的签名器的 ID |
network_type | String | 中继器将连接到的网络类型(evm 、solana ) |
network | String | 中继器将连接到的网络。必须与网络配置文件中定义的网络标识符匹配。有关定义网络的详细信息,请参阅 Network Configuration。 |
custom_rpc_urls | list | 网络的自定义 RPC URL(可选)。如果提供,则将使用此 URL 代替公共 RPC URL。这对于使用你自己的 RPC 节点或付费服务提供商很有用。列表中的第一个 URL 将用作默认 URL |
policies | list | 覆盖默认策略。请参阅 Policies 表 |
策略
网络类型 | 策略 | 类型 | 描述 |
---|---|---|---|
solana, evm | min_balance | unsigned 128 | 中继器运行所需的最小余额(以 lamports 或 wei 为单位)。可选。 |
solana | fee_payment_strategy | enum(user,relayer) | 指定谁支付费用。“user”(默认)表示发送者支付;“relayer”表示中继器支付。对于“user”,RPC 方法添加一条指令,将 SPL 代币(根据当前 SOL 价格加上可配置的保证金计算得出)从用户转移到中继器,从而确保费用以代币而不是 SOL 的形式可持续地覆盖。 |
solana | swap_config | SwapConfig | 用于在 Solana 上配置自动代币交换的可选对象。 |
solana | fee_margin_percentage | f32 | 添加到估计交易费用的额外保证金百分比,以考虑价格波动。例如,值为 10 将在估计费用上增加 10%。可选。 |
solana | max_allowed_fee_lamports | unsigned 64 | 交易允许的最大费用(以 lamports 为单位)。可选。 |
solana | allowed_tokens | Vector<AllowedToken> | 允许的代币列表。如果提供,则仅支持这些代币。可选。 |
solana | allowed_programs | Vector<String> | 按标识符列出的允许的程序列表。如果提供,则仅支持这些程序。 |
solana | allowed_accounts | Vector<String> | 按公钥列出的允许的帐户列表。如果提供,则中继器仅与这些帐户一起运行。 |
solana | disallowed_accounts | Vector<String> | 按公钥列出的不允许的帐户列表。这些帐户将被明确阻止。 |
solana | max_tx_data_size | unsigned 16 | 最大交易大小。可选。 |
solana | max_signatures | unsigned 8 | 支持的最大签名数。可选。 |
evm | gas_price_cap | unsigned 128 | 为使用中继器发送的每笔交易指定最大 gas 价格。启用后,任何超过上限的交易都将覆盖其 gasPrice 或 maxFeePerGas。(可选) |
evm | whitelist_receivers | Vector<String> | 为使用中继器发送的每笔交易授权的合约列表。如果目标地址不在列表中,则交易将被拒绝。(可选) |
中继器支持两种配置 RPC URL 的方式:
公共 RPC URL:这些是网络提供的默认 RPC 端点。它们会根据网络配置自动选择。
自定义 RPC URL:你可以使用中继器配置中的 custom_rpc_urls
字段指定自定义 RPC URL。可以为每个 URL 配置一个可选权重,以实现高可用性:
"custom_rpc_urls": [\
{\
"url": "https://primary-rpc.example.com",\
"weight": 2 // 权重越高,将更多请求路由到此端点。该值必须是介于 0 到 100(含)之间的整数。\
},\
{\
"url": "https://secondary-rpc.example.com",\
"weight": 100, // 允许的最大权重\
},\
{\
"url": "https://backup-rpc.example.com" // 未指定权重,默认为 100\
},\
{\
"url": "https://backup2-rpc.example.com",\
"weight": 0, // 值为 0 会禁用端点。\
}\
]
当你想要以下操作时,这非常有用: \ 使用你自己的带有负载平衡的 RPC 节点 \ 使用付费服务提供商以获得更好的可靠性和性能 \* 覆盖默认的公共 RPC URL \ 访问自定义网络端点 \ 配置具有不同权重的主端点和备用端点
当两者都可用时,中继器将:
1. 首先尝试使用 custom_rpc_urls
(如果已配置)。
2. 如果未配置自定义 URL,则回退到公共 RPC URL。
为了向后兼容,仍然支持字符串数组:
"custom_rpc_urls": ["https://your-rpc.example.com"]
使用自定义 RPC URL 时:<br>- 确保通过公共网络访问时,URL 是安全的(HTTPS)<br> <br>- 确保你的 API 密钥和身份验证Token安全<br> <br>- 在生产中使用 RPC 端点之前,测试其可靠性和性能<br> <br>- 配置权重以确定端点的优先级,为更可靠或性能更好的端点分配更高的值。<br> <br>- 权重必须是介于 0 到 100(含)之间的整数。<br> <br>- 权重为 0 会禁用端点。<br> <br>- 如果未为端点指定权重,则默认为 100。 |
有关如何编写插件的更多信息,请参阅 Plugins 页面。
plugins
数组,包含插件配置:"plugins": [\
{\
"id": "my-plugin",\
"path": "my-plugin.ts"\
}\
]
可用配置字段
字段 | 类型 | 描述 |
---|---|---|
id | String | 插件的唯一 ID |
path | String | 插件文件的路径 |
你可以通过以下方式配置网络:
在单独的 JSON 文件中(建议以获得更好的组织)
直接在你的主 config.json
中
有关全面的网络配置详细信息,包括:
网络字段参考
所有网络类型的配置示例
网络继承
特殊标签及其行为
最佳实践和故障排除
请参阅专门的 Network Configuration 指南。
使用密钥库签名器的 evm 和 solana 中继器定义的完整 config/config.json
示例:
{
"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\
}\
]
}
- 原文链接: docs.openzeppelin.com/re...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!