Hummingbot Injective v2 现货连接器详解:纯 Python 架构与委托账户/链上 Vault 三种账户模式配置指南
Hummingbot Injective v2 现货连接器详解:纯 Python 架构与委托账户/链上 Vault 三种账户模式配置指南
导读
本文围绕 Hummingbot 开源交易机器人中由 Injective Labs 开发的 injective_v2 现货交易连接器展开,重点讲解它与旧版 injective 连接器的本质区别(纯 Python 实现、无需 Gateway 实例),并深入剖析其支持的三种账户模式——委托账户(Delegate Account)、链上 Vault 合约账户(Off-chain Vault) 与 只读账户(Read-only Account)。读完本文,你将掌握在 Hummingbot 中配置 injective_v2 连接器所需的全部参数含义、如何通过授权脚本为交易账户授予操作权限,以及连接器内部的数据源与批量下单实现原理。
一、连接器概览:为什么 Injective 需要一个 v2 版本
1.1 v2 与旧版 injective 连接器的核心区别
根据 README 的说明,injective_v2 是一个由 Injective Labs 创建的现货(spot)连接器。它与旧版 injective 连接器的关键差异在于:
v2 是一个纯 Python 连接器(pure Python connector),用户不需要配置和运行 Gateway 实例即可使用。
这一点从源码中可以印证:连接器入口类 InjectiveV2Exchange 直接继承自 ExchangePyBase(纯 Python 交易基类),并在构造函数中通过 connector_configuration.create_data_source() 直接创建链上数据源,全程不需要 Gateway 的 RPC 中转。
从 Hummingbot 的角度看,这大大降低了接入 Injective 链的运维成本——无需额外部署和守护一个 Gateway 服务进程,只要在 Hummingbot 配置向导中填写账户参数即可完成连接。
1.2 支持的账户模式
README 明确指出,连接器支持三种账户形态(其中前两种为交易模式,第三种仅用于读取公开数据):
| 账户模式 | 用途 | 是否需要私钥/凭据 | 能否下单交易 |
|---|---|---|---|
| Delegate Account(委托账户) | 通过授权机制使用组合账户资金交易 | 需要交易账户私钥 | 是 |
| Off-chain Vault Contract(链上 Vault 合约) | 所有操作交由链上 Vault 合约执行 | 需要 Vault 管理员私钥 | 是 |
| Read-only Account(只读账户) | 仅从节点请求公开信息 | 不需要凭据 | 否 |
其中只读账户“由于不需要凭据,因此不允许执行交易操作”。在 Hummingbot 中它通常作为默认/兜底配置存在——从 injective_v2_utils.py 可以看到,account_type 字段的默认值就是 InjectiveReadOnlyAccountMode()。
二、委托账户模式(Delegate Account Mode)深度解析
2.1 模式原理
委托账户模式解决的是一个链上交易的安全性问题:用于向链上发送交易、执行下单的账户,与真正持有资金的账户不是同一个。
具体来说:
- 组合账户(Portfolio Account):持有资金的主账户,自身不直接参与交易;
- 交易账户(Trading Account):实际提交订单交易、由连接器持有其私钥的账户;
- 组合账户需要向交易账户授予权限,使其能够使用组合账户的资金进行交易。
这种"资金与交易密钥分离"的设计,可以让用户在不暴露主资金账户私钥的前提下运行交易机器人,降低资金被盗或密钥泄露的风险。
2.2 交易权限授予(Trading Permissions Grant)
要完成授权,README 指示用户参考脚本 account_delegation_script.py。该脚本位于 account_delegation_script.py,它基于 Injective 官方 Python SDK(pyinjective)构造并广播授权交易。
脚本顶部定义了一组需要用户自行填写的配置变量:
NETWORK = Network.testnet() # 选择网络:mainnet / testnet / devnet / local / custom
GRANT_EXPIRATION_IN_DAYS = 365 # 授权有效期(天)
GRANTER_ACCOUNT_PRIVATE_KEY = "" # 组合账户(granter)的私钥
GRANTER_SUBACCOUNT_INDEX = 0 # 组合账户的子账户索引(资金所在子账户)
GRANTEE_PUBLIC_INJECTIVE_ADDRESS = "" # 交易账户(grantee)的 Injective 格式地址
SPOT_MARKET_IDS = [] # 授权包含的现货市场 ID 列表
DERIVATIVE_MARKET_IDS = [] # 授权包含的衍生品市场 ID 列表
其中 SPOT_MARKET_IDS 与 DERIVATIVE_MARKET_IDS 需要填写具体的市场 ID,脚本注释中给出了查询入口:主网/测试网的 LCD 端点可以拉取全部现货与衍生品市场列表,示例格式如:
SPOT_MARKET_IDS = ["0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa"]
脚本运行时依次完成以下动作:
- 初始化 gRPC 客户端与消息组合器(
AsyncClient+composer); - 查询当前链上 Gas 价格并上浮
1.1倍(gas_price = int(gas_price * 1.1)),以保证广播时 Gas 价格依然有效; - 加载组合账户私钥,推导其公钥、地址与指定子账户 ID;
- 构造三笔授权消息并广播:
CreateSpotMarketOrderAuthz:授权在指定现货市场创建市价单;CreateDerivativeMarketOrderAuthz:授权在指定衍生品市场创建市价单;BatchUpdateOrdersAuthz:授权批量更新订单(包含现货与衍生品市场的批量下单/撤单)。
在 injective_grantee_data_source.py 中可以看到连接器实际使用 composer.msg_exec(grantee=..., msgs=...) 将交易消息**委托(exec)**给交易账户执行——这正是授权在运行时被消费的方式。
2.3 委托账户模式的配置参数
当在 Hummingbot 中创建连接器实例并选择 delegate 模式时,需要提供以下参数(README 原文参数及含义):
| 参数 | 含义 |
|---|---|
private_key |
交易账户(grantee 账户)的私钥 |
subaccount_index |
连接器将使用的、交易账户下的子账户索引(十进制数字) |
granter_address |
组合账户的公钥(Injective 格式地址) |
granter_subaccount_index |
组合账户下的子账户索引(持有资金的子账户) |
这些字段在 InjectiveDelegatedAccountMode 中得到了完整落地:四个字段均通过 pydantic Field 定义并配有配置向导提示。值得注意的实现细节是,private_key 字段的校验器(injective_v2_utils.py#L243-L252)同时支持 12 或 24 词 BIP39 助记词与十六进制私钥:若输入符合助记词正则(RE_SEED_PHRASE),会自动通过 PrivateKey.from_mnemonic 转换为十六进制私钥再使用。
三、链上 Vault 合约模式(Off-chain Vault Mode)
3.1 模式原理
当连接器配置为该模式时,所有操作都会被发送到链上的一个 Vault 合约去执行。用户需要:
- 在链上部署一个 Vault 合约;
- 使用该 Vault 的管理员账户来配置本模式的参数。
这种模式适合希望将资金托管在合约中、由合约逻辑统一管理出入金与权限的场景,资金不直接暴露在任一个体账户私钥之下。
3.2 模式参数
在 Hummingbot 中配置该模式时,README 规定的必需参数如下:
| 参数 | 含义 |
|---|---|
private_key |
Vault 管理员的账户私钥 |
subaccount_index |
Vault 管理员账户下的子账户索引(十进制数字) |
vault_contract_address |
链上 Vault 合约的地址 |
需要说明的是:就当前仓库源码而言,account_type 的可选项在 injective_v2_utils.py#L287-L290 的 ACCOUNT_MODES 字典中实际落地为 delegate_account 与 read_only_account 两种(另有只读模式作为默认值);README 中描述的 Vault 模式属于文档记载的官方支持方向,其运行时依赖 Vault 合约的部署与 vault_contract_address 的可用性,使用前请以所部署的 Hummingbot 版本实际提供的配置项为准。
四、只读账户模式(Read-only Account Mode)
只读账户模式是第三种账户类型,它只允许从节点请求公开信息。由于不涉及任何凭据(不需要私钥),它不能执行任何交易操作。
在代码层面,InjectiveReadOnlyDataSource 与委托模式的数据源共用同一个抽象基类 InjectiveDataSource,但只初始化 AsyncClient 与 IndexerClient 用于查询,其 portfolio_account_injective_address 等交易相关属性直接 raise NotImplementedError,从结构上杜绝了交易能力。
这一模式在实际使用中的价值在于:无需任何密钥即可先运行 Hummingbot 拉取行情、获取交易对与市场数据,用于回测、行情监控或作为只读行情源,是零门槛体验该连接器的入口。
五、连接器配置向导中的完整配置项
除了账户模式参数,Hummingbot 在创建 injective_v2 连接器时还会引导用户配置另外两类选项,它们由 InjectiveConfigMap 统一管理:
5.1 网络模式(network)
| 模式 | 说明与参数 |
|---|---|
mainnet_network |
主网,直接使用 Network.mainnet() |
testnet_network |
测试网,需选择测试网节点 testnet_node,可选值为 lb 或 sentry(默认 lb,校验见 injective_v2_utils.py#L122-L127) |
custom_network |
自定义网络,需填写 lcd_endpoint、tm_websocket_endpoint、grpc_endpoint、grpc_exchange_endpoint、grpc_explorer_endpoint、chain_stream_endpoint、chain_id、env 共 8 个端点/参数 |
不同网络的限流策略也不同:主网与测试网走 PUBLIC_NODE_RATE_LIMITS(链端点组 20 req/s、索引器端点组 50 req/s),自定义网络则不做限流(CUSTOM_NODE_RATE_LIMITS 为 sys.maxsize),这些定义位于 injective_constants.py#L134-L144。
5.2 手续费计算器(fee_calculator)
| 模式 | 说明 |
|---|---|
simulated_transaction_fee_calculator |
通过交易模拟(SimulateTransaction)计算 Gas 费用 |
message_based_transaction_fee_calculator |
基于消息类型使用 Gas 启发式计算费用,为默认值 |
两者都封装在 injective_v2_utils.py#L42-L94 的 InjectiveFeeCalculatorMode 抽象体系下,最终由 InjectiveGranteeDataSource._configure_gas_fee_for_transaction 在广播交易前为每笔交易配置 Gas 费用。
5.3 默认费用与交易对示例
连接器将默认手续费率设为 0(DEFAULT_FEES,maker 与 taker 均为 0),示例交易对为 INJ-USDT。在 injective_data_source.py#L652-L662 中,实际交易费率会从链上市场信息(get_spot_trading_fees)动态拉取并缓存,而不是写死。
六、源码级实现:连接器如何工作
6.1 分层架构
injective_v2 的代码组织体现了清晰的职责分层(目录 hummingbot/connector/exchange/injective_v2):
- injective_v2_exchange.py:交易所入口类,负责订单跟踪、事件分发、余额更新等 Hummingbot 标准接口;
data_sources/injective_data_source.py:抽象数据源基类,定义链上查询与交易消息的抽象接口;data_sources/injective_grantee_data_source.py:委托账户模式的实现;data_sources/injective_read_only_data_source.py:只读模式的实现;- injective_v2_api_order_book_data_source.py:订单簿数据源;
- injective_query_executor.py:封装 gRPC 与索引器查询执行;
- injective_v2_utils.py:pydantic 配置模型(
InjectiveConfigMap); - injective_constants.py:限流规则、订单状态映射、事件名等常量。
6.2 批量下单与批量撤单
与大多数逐单发送 HTTP 请求的 CEX 连接器不同,Injective 的每个操作都需要构造链上交易(Transaction)。为此,连接器做了两个关键设计:
- 单笔下单请求会被排队,攒批后统一通过一笔交易提交。在 injective_v2_exchange.py#L358-L361 中,
_place_order_and_process_update把单个订单追加到_orders_queued_to_create队列;后台任务_process_queued_orders周期性调用_cancel_and_create_queued_orders(injective_v2_exchange.py#L932-L940)统一执行批量下单/撤单; - 订单创建与取消的确认不依赖 HTTP 响应,而是监听链上交易。
create_orders将整批订单打包进一笔交易广播后,返回的creation_transaction_hash会被写入订单的misc_updates;随后_check_orders_transactions周期性检查该交易是否已上链、并根据链上事件更新订单状态(injective_v2_exchange.py#L863-L911)。
6.3 账户、余额与订单流
在委托模式下,连接器始终以组合账户的身份视角获取数据:
- 余额:
all_account_balances()查询组合账户的bankBalances与子账户持仓(injective_data_source.py#L334-L375); - 订单:通过
spot_order_updates按市场 ID 与起始时间拉取历史订单,状态经 ORDER_STATE_MAP(booked/partial_filled/filled/canceled)映射为 Hummingbot 的OrderState; - 链上事件:数据源通过
chain_stream与transactions两种流监听更新,并经由PubSub事件转发器(_configure_event_forwarders)把TradeUpdate、OrderUpdate、余额与交易事件送入_all_trading_events_queue,由_user_stream_event_listener统一消费处理(injective_v2_exchange.py#L624-L667)。
值得一提的还有交易对映射:Injective 的市场 ticker 并非唯一,因此连接器在 trigger_event 中用 real_tokens_spot_trading_pair 将事件里的交易对替换为真实代币交易对,避免影响策略事件处理(injective_v2_exchange.py#L264-L277)。
6.4 测试支撑
仓库中为该连接器提供了较完整的测试覆盖,目录 test/hummingbot/connector/exchange/injective_v2 包含:
test_injective_v2_exchange_for_delegated_account.py:委托账户模式下交易所核心逻辑的端到端测试;test_injective_v2_api_order_book_data_source.py:订单簿数据源测试;test_injective_market.py、test_injective_v2_utils.py、test_injective_data_source.py:市场模型、配置工具与数据源测试。
其中测试还借助 programmable_query_executor.py 构造可编程的查询执行器来模拟链上响应,说明连接器在设计上对查询层做了良好的依赖注入,便于离线下单逻辑的验证。
七、配置与使用建议小结
综合 README 与源码,使用 injective_v2 连接器的推荐路径如下:
- 确定网络:选择
mainnet_network、testnet_network(可选lb/sentry节点)或custom_network; - 选择账户模式:
- 有交易机器人安全隔离需求 →
delegate_account:先用account_delegation_script.py完成权限授予,再填写private_key、subaccount_index、granter_address、granter_subaccount_index; - 已有部署好的 Vault 合约 → 使用 Vault 模式,填写管理员私钥与合约地址;
- 仅做行情/回测 →
read_only_account,无需任何密钥;
- 有交易机器人安全隔离需求 →
- 选择手续费计算器:默认
message_based_transaction_fee_calculator即可,追求更精确的 Gas 可用模拟模式; - 启动前核对:确认交易账户具备足够的原生代币用于支付 Gas(连接器会基于实时链上 Gas 价格上浮 1.1 倍进行配置),并确保授权尚未过期(脚本默认 365 天)。
结语
injective_v2 是 Hummingbot 生态中一个典型的"原生链上型"连接器:以纯 Python 方式直连 Injective 链,通过委托授权与 Vault 合约两种模式解决资金安全与交易执行之间的平衡,同时用批量交易、链上事件监听等机制适配了 Cosmos SDK 系的交易模型。无论你是希望将 Injective 现货市场接入自动做市或方向性策略,还是想以只读方式先行验证行情数据,都可以从本文的参数表与源码路径入手,快速完成连接器配置并深入理解其运行原理。