本文档介绍了OpenZeppelin Relayer的配置方法,包括基于文件的配置(config.json和.env文件)和基于API的配置。涵盖了环境变量配置、主配置文件结构(包括Signers、Notifications、Relayers、Networks和Plugins的详细配置),以及不同配置管理方法的优缺点。
大多数配置文件应该位于./config
下,包括签名器配置,位于./config/keys
下。
请确保所有配置文件具有适当的访问权限(对于./config/keys/*
,我们建议0500
)。
OpenZeppelin Relayer 支持两种配置方法:<br>基于文件的配置:<br>1. config.json : 包含 relayer 定义、签名器配置和网络策略<br>2. .env 文件:包含 API 密钥和连接字符串等环境变量<br>基于 API 的配置:<br>- 通过 REST API 对 relayers、签名器和通知执行完整的 CRUD 操作<br>- 更改立即生效(无需重新启动容器)<br>- 有关详细的端点文档,请参见 API 参考 页面<br>有关基于文件和基于 API 的配置如何协同工作、存储行为和最佳实践的详细信息,请参见 存储配置。<br>有关使用预配置文件的快速设置示例,请参见我们 GitHub 存储库中的 examples directory。 |
这定义了 Relayer 应用程序的一些基本配置:
复制示例环境变量文件,并根据你的需要更新值
cp .env.example .env
下表列出了环境变量及其默认值。
环境变量 | 默认值 | 接受的值 | 描述 |
---|---|---|---|
RUST_LOG |
info |
info, debug, warn, error, trace |
日志级别。 |
REPOSITORY_STORAGE_TYPE |
in-memory |
in-memory, redis |
用于存储仓库配置和资源的存储类型。有关详细信息,请参见 存储配置。 |
RESET_STORAGE_ON_START |
false |
bool |
启动时清除存储中的所有资源,并从配置文件重新加载条目。有关使用详情,请参见 存储配置。 |
TRANSACTION_EXPIRATION_HOURS |
4 |
number |
最终状态的交易从存储中移除的小时数。有关更多信息,请参见 存储配置。 |
CONFIG_DIR |
./config |
<config.json 所在的任何相对文件路径> |
配置文件所在的目录的相对路径 |
CONFIG_FILE_NAME |
config.json |
<任何文件名> |
配置文件的文件名。 |
RATE_LIMIT_RPS |
100 |
<任何值> |
API 的速率限制,以每秒请求数为单位。 |
RATE_LIMIT_BURST_SIZE |
300 |
<任何值> |
速率限制突发大小。 |
API_KEY |
` | string` |
用于 Relayer 服务器身份验证的 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 连接字符串> |
Relayer 的 Redis 连接 URL。有关 Redis 设置详情,请参见 存储配置。 |
REDIS_CONNECTION_TIMEOUT_MS |
10000 |
<以毫秒为单位的超时> |
Redis 的连接超时时间,以毫秒为单位。有关 Redis 配置,请参见 存储配置。 |
REDIS_KEY_PREFIX |
oz-relayer |
string |
用于命名空间的 Redis 密钥前缀。有关更多信息,请参见 存储配置。 |
STORAGE_ENCRYPTION_KEY |
` | string` |
用于加密 Redis 存储中静态数据的加密密钥。有关安全详情,请参见 存储配置。 | |
RPC_TIMEOUT_MS |
10000 |
<以毫秒为单位的超时> |
设置 RPC 连接在超时之前等待的最长时间。 |
PROVIDER_MAX_RETRIES |
3 |
<重试次数> |
提供程序操作的最大重试次数。 |
PROVIDER_RETRY_BASE_DELAY_MS |
100 |
<以毫秒为单位的延迟> |
重试尝试之间的基本延迟,以毫秒为单位。 |
PROVIDER_RETRY_MAX_DELAY_MS |
2000 |
<以毫秒为单位的延迟> |
重试尝试之间的最大延迟,以毫秒为单位。 |
PROVIDER_MAX_FAILOVERS |
3 |
<故障转移次数> |
最大故障转移次数(切换到不同的提供程序)。 |
ENABLE_SWAGGER |
false |
true, false |
启用或禁用 API 文档的 Swagger UI。 |
KEYSTORE_PASSPHRASE |
` | <密钥库密码>` |
用于签署交易的密钥库文件的密码。 |
.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
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
此文件可以存在于任何目录中,但默认位置是 ./config/config.json
。
config.json 中定义的所有组件也可以通过 REST API 端点进行管理。这为添加、更新或删除 relayers、签名器和通知提供了运行时灵活性,而无需重新启动服务。有关详细的端点文档,请参见 API 参考 页面。 |
此文件中的关键部分包括:
签名器:定义交易签名方法。
通知:设置状态警报
Relayers:配置网络、通知渠道、策略和歌手。
网络:定义区块链网络配置。
插件:配置插件。
交易签名器负责在将交易提交到区块链网络之前对其进行加密签名。
有关配置所有受支持的签名器类型的全面详细信息,包括:
本地密钥库文件签名器
HashiCorp Vault(密钥和传输)
Cloud KMS 提供商(Google Cloud、AWS)
Turnkey 签名器
安全最佳实践和故障排除
请参见专门的 签名器配置 指南。
签名器也可以通过 API 端点进行管理。<br> 有关详细的端点文档,请参见 API 参考 页面。 |
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 | 签名密钥值、环境变量名称... |
通知也可以通过 API 端点进行管理。<br>有关详细的端点文档,请参见 API 参考 页面。 |
relayers
数组,包含 relayer 条目:"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 之间的整数(包括 0 和 100)。
},
{
"url": "https://backup-rpc.example.com",
"weight": 1
}
],
"policies": {
"allowed_programs": [
"11111111111111111111111111111111",
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"BPFLoaderUpgradeab1e11111111111111111111111"
]
}
}
]
可用配置字段
字段 | 类型 | 描述 |
---|---|---|
id | String | relayer 的唯一 ID |
name | String | relayer 的人类可读名称 |
paused | Boolean | relayer 是否已暂停( true ,false ) |
notification_id | String | 配置的通知对象的 ID |
signer_id | String | 配置的签名器的 ID |
network_type | String | relayer 将连接到的网络类型( evm ,solana ) |
network | String | relayer 将连接到的网络。必须与你的网络配置文件中定义的网络标识符匹配。有关定义网络的详细信息,请参见 网络配置。 |
custom_rpc_urls | list | 网络的可选自定义 RPC URL。如果提供,将使用此 URL 代替公共 RPC URL。这对于使用你自己的 RPC 节点或付费服务提供商很有用。列表中的第一个 URL 将用作默认值 |
policies | list | 覆盖默认策略。请参阅 Policies 表 |
策略
网络类型 | 策略 | 类型 | 描述 |
---|---|---|---|
solana, evm | min_balance | unsigned 128 | relayer 运行所需的最小余额(以 lamports 或 wei 为单位)。可选。 |
solana | fee_payment_strategy | enum(user,relayer) | 指定谁支付费用。“user”(默认值)表示发送者支付;“relayer”表示 relayer 支付。对于“user”,RPC 方法会添加一条指令,将 SPL 代币(根据当前 SOL 价格加上可配置的保证金计算得出)从用户转移到 relayer,确保费用以代币而不是 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> | 按公钥列出的允许帐户列表。如果提供,则 relayer 仅与这些帐户一起运行。 |
solana | disallowed_accounts | Vector<String> | 按公钥列出的不允许帐户列表。这些帐户将被明确阻止。 |
solana | max_tx_data_size | unsigned 16 | 最大交易大小。可选。 |
solana | max_signatures | unsigned 8 | 支持的最大签名数。可选。 |
evm | gas_price_cap | unsigned 128 | 为 Relayer 发送的每笔交易指定最大 gas 价格。启用后,任何超过上限的交易都将覆盖其 gasPrice 或 maxFeePerGas。(可选) |
evm | gas_limit_estimation | bool | 自动 gas_limit 计算。默认启用。(可选) |
evm | whitelist_receivers | Vector<String> | 使用 Relayer 发送的每笔交易的授权合约列表。如果目标地址不在列表中,则交易将被拒绝。(可选) |
Relayer 支持两种配置 RPC URL 的方式:
公共 RPC URL:这些是网络提供的默认 RPC 端点。它们会根据网络配置自动选择。
自定义 RPC URL:你可以使用 relayer 配置中的 custom_rpc_urls
字段指定自定义 RPC URL。可以为每个 URL 配置一个可选权重,以实现高可用性:
"custom_rpc_urls": [
{
"url": "https://primary-rpc.example.com",
"weight": 2 // 较高的权重会将更多请求路由到此端点。该值必须是介于 0 和 100 之间的整数(包括 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 会禁用端点。
}
]
当你想要执行以下操作时,这非常有用:
当两者都可用时,relayer 将执行以下操作:
custom_rpc_urls
,则首先尝试使用它。为了向后兼容,仍然支持字符串数组:
"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 之间的整数(包括 0 和 100)。<br> <br>- 权重 0 会禁用端点。<br> <br>- 如果未为端点指定权重,则默认为 100。 |
Relayers 也可以通过 API 端点进行管理。<br>有关详细的端点文档,请参见 API 参考 页面。 |
有关如何编写插件的更多信息,请参阅 插件 页面。
plugins
数组,包含插件配置:"plugins": [
{
"id": "my-plugin",
"path": "my-plugin.ts"
}
]
可用配置字段
字段 | 类型 | 描述 |
---|---|---|
id | String | 插件的唯一 ID |
path | String | 插件文件的路径 |
你可以配置网络:
在单独的 JSON 文件中(建议用于更好地组织)
直接在你的主 config.json
中
有关全面的网络配置详细信息,包括:
网络字段参考
所有网络类型的配置示例
网络继承
特殊标签及其行为
最佳实践和故障排除
请参见专门的 网络配置 指南。
完整的 config/config.json
示例,其中包含使用密钥库签名器的 evm 和 solana relayers 定义:
{
"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
}
]
}
OpenZeppelin Relayer 支持两种互补的配置管理方法:
适合初始设置和部署
配置在重启后仍然存在
需要重新启动容器才能使更改生效
适用于基础设施即代码工作流程
启用运行时配置更改
无需重启服务
非常适合动态环境
支持自动化配置管理
有关基于文件和基于 API 的配置如何协同工作、存储行为和最佳实践的详细信息,请参见 存储配置。
- 原文链接: docs.openzeppelin.com/re...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!