mcpField
R
Reins

Reins

本地服务
r2rlabs.com金融数据04 周前更新

关于 Reins

Reins 是面向使用 AI Agent 交易 Hyperliquid 的 MCP 服务,在模型之外执行风险限制并记录交易决策。它提供使用真实价格的模拟交易,便于在实盘前测试。

主要功能

  1. 01模型外执行仓位与杠杆限制
  2. 02限制市场范围及每日亏损
  3. 03记录决策、拒绝操作与成交
  4. 04使用真实价格进行模拟交易
  5. 05支持 Hyperliquid 实盘下单

适用场景

  1. 01在模拟账户中测试交易 Agent
  2. 02阻止超限订单送达交易所
  3. 03审查 Agent 决策及交易结果

MCP 相关

向 MCP 客户端提供经过风险检查并记录的交易工具,涵盖 Hyperliquid 交易操作。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"r2rlabs-hyperliquid-reins": {
"command": "npx",
"args": [
"-y",
"@r2rlabs/reins"
],
"env": {
"REINS_SYMBOLS": "<REINS_SYMBOLS>",
"REINS_MAX_POSITION_USD": "<REINS_MAX_POSITION_USD>",
"REINS_DAILY_LOSS_USD": "<REINS_DAILY_LOSS_USD>",
"REINS_MAX_LEVERAGE": "<REINS_MAX_LEVERAGE>",
"REINS_MODE": "<REINS_MODE>",
"REINS_NETWORK": "<REINS_NETWORK>",
"REINS_REQUIRE_STOP_LOSS": "<REINS_REQUIRE_STOP_LOSS>",
"REINS_LOG_FILE": "<REINS_LOG_FILE>",
"REINS_PAPER_FILE": "<REINS_PAPER_FILE>",
"REINS_ACCOUNT_ADDRESS": "<REINS_ACCOUNT_ADDRESS>",
"REINS_PRIVATE_KEY": "<REINS_PRIVATE_KEY>"
}
}
}
}
启动命令npx -y @r2rlabs/reins
需要配置的环境变量
REINS_SYMBOLSMarkets the agent may trade, comma separated, e.g. BTC,ETH. Every other market is refused.
REINS_MAX_POSITION_USDLargest position per market, in USD.
REINS_DAILY_LOSS_USDRealised loss in a UTC day after which new risk is refused.
REINS_MAX_LEVERAGELargest total exposure as a multiple of account value.
REINS_MODEpaper (live prices, simulated fills, nothing signed) or live.
REINS_NETWORKHyperliquid network for prices and, in live mode, orders. Mainnet spends real money.
REINS_REQUIRE_STOP_LOSStrue to refuse any order that adds risk without a stop-loss.
REINS_LOG_FILEDecision log, one JSON line per action with the agent's stated reason. In memory if unset.
REINS_PAPER_FILEWhere the paper account is kept between runs. In memory if unset.
REINS_ACCOUNT_ADDRESSLive mode: the Hyperliquid account traded. Approve Reins' 2 bp builder fee from it first: npx @r2rlabs/reins approve-builder
REINS_PRIVATE_KEY密钥Live mode: an API wallet's key, which can trade but not withdraw. Never the account's own key.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@r2rlabs/reins0.1.8

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Reins

让 AI Agent 进行交易,同时不赋予它让你血本无归的能力。

npx @r2rlabs/reins init      # adds a paper-trading Reins server to .mcp.json

看看它的实际表现:AI Agent 在 Hyperliquid 上进行模拟交易,第 2 次运行。

源代码托管在 GitHub 上:R2Rlabs/reins。本 README 中的每一项限制,都是你可以阅读的函数。

Reins 是什么
  • Agent 无法辩驳的限制。 每笔订单都要通过模型之外的检查:持仓规模、杠杆、每日亏损、允许交易的市场,以及每个持仓的止损。提示词、巧妙推理或失误都无法绕过这些限制。
  • 可供核查的记录。 每个决策都会连同 Agent 给出的理由一起记录下来——包括被拒绝的订单、选择等待的时刻,以及交易所自行采取的操作。你可以对比 Agent 说了什么 和实际 发生了什么。
  • 可供演练的环境。 使用与实盘交易相同的工具和限制,根据实时 Hyperliquid 价格进行模拟交易,并采用逼真的成交和费用。
  • 非托管。 你的资金留在自己的 Hyperliquid 账户中。Reins 通过 API 钱包进行交易;该钱包可以下单,但不能提现。
  • 费用公开透明。 实盘订单收取少量构建者费用(2 bp),并会提前说明。
Reins 不是什么
  • 不是交易机器人,也不是策略。 Reins 不会决定交易什么,也不会让 Agent 盈利。演示 Agent 只是试用示例,并非产品本身。
  • 不是交易所、经纪商或托管方。 它不持有资金,也不撮合订单;这些都由 Hyperliquid 负责。
  • 不保证避免亏损。 限制可以控制最坏情况下的损失,但无法让糟糕的交易变好;在快速波动的市场中,止损也可能出现滑点。
  • 不是财务建议。
  • 不需要你盲目信任。 无论是 Agent 的说法,还是我们的说法都不必轻信:每项操作都有记录。
原则
  1. 限制位于模型之外。
  2. 记录比推理更重要。
  3. 先模拟,再投入真金白银。
  4. 你的密钥,你的资金。

为什么要做这个项目

目前已有多个开源 Hyperliquid MCP 服务。它们只是简单的 API 封装:你交出私钥,然后祈祷模型行为得当。而缺失的是与之相关的一切——限制、沙盒和审计记录。这正是本仓库要解决的问题。

状态

项目尚处早期,但已具备实际功能。共有 391 项测试,且没有一项会发起网络请求。

模块功能
src/risk.ts风险引擎——持仓上限、单笔交易风险、杠杆上限、每日亏损停机、允许列表、速率限制
src/client.tsHyperliquid REST 客户端——订单、撤单、盘口、K 线、成交记录、账户状态、构建者代码
src/mcp-server.ts面向 Agent 的工具,每项工具在发送任何内容前都会经过风险检查并记录日志
src/paper.ts模拟交易——实时价格、模拟成交。见下文
src/paper-store.ts在重启后保留模拟交易运行状态
src/trading-client.ts实盘和模拟交易共同实现的接口
src/decision-log.ts仅追加记录每次尝试及其给出的理由
src/decision-log-file.ts磁盘上的 JSON Lines 日志
src/bin/cli.tsreins 命令:serve(默认)、init、approve-builder、live-check、http 和 stats
src/bin/serve.tsstdio 入口
src/bin/http.tsreins http——HTTP 服务:令牌、绑定、JSON
src/http-api.ts与 MCP 相同的九个工具,以 HTTP 路由提供,供不支持 MCP 的机器人使用
src/runtime.ts两种入口共用的限制、客户端、日志和横幅
src/init.tsreins init——将模拟模式的服务条目写入 .mcp.json
src/builder-fee.tsReins 的构建者费用,以及开始实盘交易前所需的批准
src/approve-builder.tsreins approve-builder——用户在自己的钱包中批准构建者费用
src/live-check.tsreins live-check——验证实盘交易所是否接受 Reins 发送的内容
src/platform-stats.tsreins stats——通过 Reins 的构建者代码查看账户、交易、交易量和费用
src/lz4.ts无需依赖项即可读取 Hyperliquid 的 LZ4 压缩数据文件
src/builder-approval.tsApproveBuilderFee 操作:EIP-712 类型化数据、签名检查
src/format.ts按照 Hyperliquid 的最小价格变动和交易单位规则格式化价格和数量
src/signing.tsL1 操作签名,已通过 Python SDK 的测试向量验证
src/private-key-signer.ts由私钥支持的 Signer
src/signer.tsSigner 接口和一个存根。见下文“关于签名”
src/mock-transport.ts内存中的 API 替身,可在不访问网络的情况下测试 Agent
examples/demo-agent/Claude 通过 Reins 进行模拟交易,并生成可发布的决策日志

所有功能都已端到端打通。现在只需为账户注资,并使用密钥设置 REINS_MODE=live,即可开始实盘交易。

正式运行
REINS_MODE=live
REINS_NETWORK=testnet          # mainnet spends real money
REINS_ACCOUNT_ADDRESS=0x...    # your Hyperliquid account
REINS_PRIVATE_KEY=0x...        # an API wallet's key, not your account's; omit to stay read-only

在主网首次进行实盘会话之前,请先从账户自己的钱包批准 Reins 的 2 bp 构建者费用:npx @r2rlabs/reins approve-builder。在账户完成批准之前,实盘模式会拒绝启动并说明原因。

请使用 API 钱包,而不是账户自己的密钥。 Hyperliquid 允许账户批准可代其交易、但无法从账户提款的 API 钱包——请在 Hyperliquid 的 API 页面创建一个,并使用主钱包签署批准。将其密钥填入 REINS_PRIVATE_KEY,并将账户地址填入 REINS_ACCOUNT_ADDRESS:订单由 API 钱包签名,而持仓、成交和止损则从账户读取,因为在 API 钱包自己的地址下,账户看起来是空的。启动横幅会显示这两个地址。Hyperliquid 会清除已过期或被替换的 API 钱包;请创建新的钱包,不要重复使用旧地址。

所有账户模式均可使用。Hyperliquid 会将新账户设为 Unified 模式,此时 USDC 存放在现货余额中,而永续合约账户显示为 $0;Reins 会查询账户所处模式,并在 Unified 和 Portfolio 保证金模式下,从 USDC 余额加上持仓未实现盈亏中计算权益。手动账户仍像以前一样从永续合约账户读取。(构建者地址则不同:必须处于 Manual(standard)模式才能赚取费用。)

默认设置经过刻意设计,以确保安全:REINS_MODE 为 paper,REINS_NETWORK 为 testnet,因此要交易真实资金,必须明确修改两项设置,而不是因忘改一个变量就意外启动实盘。实盘模式在没有密钥时仍保持只读,而不会等到第一笔订单才失败;主网启动时会显示醒目的横幅。

私钥仅在实盘模式下读取——纸面交易不会签名任何内容,因此不会获得使用该密钥的能力。

查看运行效果

npm run build
npm run demo -- --scripted      # free: no API key, live prices, paper fills

提供 Anthropic API 密钥后,运行 npm run demo,即可在严格的支出上限下让 Claude 作为 Agent 运行。费用、限制以及如何如实发布结果,请参阅 examples/demo-agent。

决策日志

每次尝试执行的操作都会连同 Agent 给出的理由一起追加到日志中——包括被风险限制拒绝的操作。 这正是重点。“凌晨 3 点,Agent 试图开仓,仓位上限是其六倍,这是它声称自己要做的事”,这是该系统能告诉你的最有用信息;只有将拒绝记录下来,这些信息才会存在。

place_order、close_position 和 set_stop_loss 都必须提供 reason。可选字段可能会被省略;必填字段则必须回答。

记录采用 JSON Lines 格式——每行都是一个独立完整的对象,只追加,绝不重写。随着文件增大,追加操作仍然开销低;写入被截断时,只会损坏一行,而不是整个文件;你还可以使用常见工具查询:

jq -r 'select(.risk.allowed == false) | [.time, .risk.code, .reason] | @tsv' decisions.jsonl

每条记录都包含说明的理由、请求、当时的账户上下文、风险判定和操作结果。设置 REINS_LOG_FILE 可将日志持久化;如果不设置,日志会保存在内存中,并随进程结束而消失。

交易所也会自行采取行动:止损触发,或者挂单在下单数小时后成交。每次调用工具之前,Reins 都会将账户的成交记录与日志进行比较,并把它尚未见过的每笔成交追加为 exchange_fill 记录。记录的理由以“这不是 Agent 的决策:”开头,并说明这是止损、挂单,还是 Reins 未下达的成交。如果没有这些记录,最重要的交易——平仓的止损——就会从日志中缺失。Agent 会像读取其他记录一样,通过 get_recent_decisions 读取这些记录。

需要明确的两件事

reason 是陈述,不是真相。 它是模型对自身行为原因的说明,我们将其记录下来,是因为如果不要求模型进行推理,事后就无法还原。模型可能会事后为自己的行为找理由,而自信的解释并不能证明这就是实际驱动决策的原因。它对调试和审计非常有用,但并非证据。

日志写入失败绝不会导致已成交订单失败。 如果无法写入日志,工具仍会报告成功,并附上警告。若告知 Agent 订单失败,它就会再次下单——因此,丢失一条日志可能导致头寸翻倍,这比缺少日志严重得多。风险引擎是安全机制;日志用于可观测性。

模拟交易

REINS_MODE=paper(默认值)会使用真实价格进行模拟成交,运行相同的工具、风险引擎和 Agent。不会签署任何内容,也不会向交易所发送任何内容。

模拟交易和实盘交易通过同一个接口切换,因此 Agent 无法分辨自己连接的是哪一种——这正是目的所在。在模拟交易中有效的策略,在实盘中也能原样运行。

模拟内容
  • 真实订单簿深度。 大额订单会逐档成交并承担实际滑点,而不是全部按触价成交。
  • 当订单簿在限价范围内深度不足时,会发生部分成交。
  • Taker 和 Maker 手续费按 Hyperliquid 基础费率收取(0.045% / 0.015%),另加任何 Builder 费用,因此权益曲线反映的是扣除实际交易成本后的结果。
  • 挂单只有在市场价格严格穿过挂单价时才会成交,仅触及价格并不会成交。在你自己的价格上,你排在模拟看不到的队列之后;假设此时能够成交,是模拟权益曲线最常见的失真方式。
  • 轮询间隔期间的成交。 每次调用都会检查挂单之后生成的一分钟 K 线,而不只是当时的订单簿;如果市场穿过挂单价,则按市场首次穿过该价格的那一分钟成交。若订单已成交,则会拒绝取消,就像交易所一样。此前,演示 Agent 的突破买单在持续两分钟的下跌中一直未成交,随后它取消了一个 Hyperliquid 已经会成交的订单。
未模拟的内容

前五项会使结果显得更好;后两项可能会导致漏掉成交。这里逐项列出,不会隐瞒:

  • 延迟——成交价格基于调用工具时的订单簿
  • 市场冲击——你的订单不会推动价格,也不会消耗流动性
  • 永续合约的资金费
  • 已过去的一分钟内,止损价位之外的滑点——如果在过去的 K 线中发现止损已触发,则按触发价成交;如果市场跳空越过止损价,则按该 K 线的开盘价成交。刚刚触发的止损会按真实订单簿逐档成交。
  • 标记价格——Hyperliquid 根据标记价格触发止损;模拟交易使用成交价格,两者可能短暂不同
  • 下单所在的那一分钟——只统计下单后第一个开始的一分钟 K 线,因此会漏掉同一分钟内的下跌
  • 挂单时间超过约三天的订单——最多只能获取最新的 5000 根一分钟 K 线,因此不会检查更早的时间段

请将模拟权益曲线视为实盘表现的上限,而不是对实盘表现的估算。

运行模拟账户
{
  "env": {
    "REINS_MODE": "paper",
    "REINS_PAPER_BALANCE": "10000",
    "REINS_PAPER_FILE": "./paper-run.json"
  }
}

如果未设置 REINS_PAPER_FILE,账户数据会保存在内存中,重启后便会丢失。若计划运行超过一个会话,请设置该变量——数据会先写入临时文件,再重命名到目标位置,因此即使发生崩溃,也不会留下只写了一半的运行记录。

MCP 服务

九种工具。每个可能转移资金的工具都会先经过风险引擎,且每次尝试都会写入决策日志。

工具说明
get_limits限额、每个交易对的可用额度、剩余亏损预算、暂停状态
get_positions每个交易对的带符号名义价值、账户价值、今日已实现 PnL、止损,以及哪些持仓没有止损
get_book最优买价/卖价、价差、最近的档位
get_candles以 1m 到 1d K 线表示的价格历史、单根 K 线的平均振幅,以及最新一根是否仍在形成
place_order以 USD 计量,而非资产单位——与限额使用相同的单位。立即成交的订单可选 stopLoss
set_stop_loss为整个持仓设置止损,或移动止损;由交易所托管
cancel_order按交易所订单 ID 撤单,包括止损单
close_position仅减仓,跨越价差;即使处于暂停状态也可执行
get_recent_decisions重启后查看 Agent 自身近期的操作及原因

被拦截的订单会作为工具错误返回,并附带具体原因 (BLOCKED (POSITION_TOO_LARGE): Would put BTC at $61,400, over the $25,000 cap), 这样 Agent 可以自行修正,而不是重试同一笔被拒绝的订单。没有任何工具可以更改限额。

订单永远不是真正的市价单——不带价格的 place_order 会成为可成交限价单,以小幅缓冲价跨越价差,因此即使盘口较薄,也不会让 Agent 以不受限制的价格成交。

止损

如果 Agent 说“价格跌破 2,630 我就离场”,那就只能依赖它下次醒来时的行动。止损会将其转化为一笔由交易所托管并执行的订单,让 Agent 即使休眠也能生效:当价格触及触发价时,触发一笔仅减仓的市价止损单,按市价平掉整个持仓。

  • set_stop_loss 会为当前整个持仓设置止损,并替换该交易对上已有的任何止损——先挂上新止损,再撤掉旧止损,因此持仓在此期间不会出现止损空档。若触发价设在市场的错误一侧(会立即触发),则会拒绝该操作。
  • place_order 配合 stopLoss 可在同一次调用中保护入场。立即成交的订单会在成交后立刻为整个持仓设置止损;如果止损设置失败,成交仍然有效,Agent 也会收到明确提示,得知该持仓没有保护。挂单会附带止损,交易所会在订单每部分成交时分别为其设置止损,因此以较低的 Maker 费率在盘口等待成交的入场单,一旦成交就不会处于无保护状态。
  • close_position 会在平掉持仓的同时撤掉止损。
  • REINS_REQUIRE_STOP_LOSS=true 会将止损从习惯变为硬性要求:对于没有附带自身 stopLoss 却会增加风险的订单,风险引擎会予以拒绝;如果当前持仓没有覆盖全部持仓的止损(NO_STOP_LOSS),任何增加风险的操作也会被拒绝。减少风险的操作永远不会被拦截。

在底层通信中,独立止损单就是 Hyperliquid 的 Python SDK 在其 tpsl 测试向量中签名的触发单,而 signing.test.ts 会在两个网络上逐字节复现该向量。挂单及其止损会通过 normalTpsl 分组一同发出,正如 SDK 的 basic_tpsl 示例所示。止损的最差成交价会比触发价高出 5% 的滑点空间——这是 SDK 自带的默认滑点——因为无法成交的止损毫无保护作用。模拟模式会从与挂单相同的一分钟 K 线中触发止损,并按照市场触及它们的先后顺序执行;如果某笔成交是在过去的 K 线中发现的,那么附加在该成交上的止损也会监控那一分钟,因为仅凭 K 线无法判断两者谁先发生。这两种止损方式以及移动止损,均已于 2026-09-21 在 live-check --trade 中由已入金账户通过主网验证。

运行
npx @r2rlabs/reins init         # from a clone: npm run build && node dist/bin/cli.js init

init 会将一个 paper-mode reins 服务添加到 ./.mcp.json(保留其中的其他服务),并应用以下限制:最大持仓 $5,000、每日亏损 $500、BTC 和 ETH,以及决策日志和模拟账户的绝对路径。可通过标志更改这些设置(--symbols SOL,BTC --max-position 2500),通过 --file 写入其他位置,或改用 --print 打印配置项。它绝不会写入 live 模式或密钥;若已有 reins 配置项,则不会覆盖,除非指定 --force。运行 reins init --help 可查看全部选项。

Reins 会对 live mainnet 订单收取 2 bp 的构建者费用,费用支付给 src/builder-fee.ts 中的 REINS_BUILDER_ADDRESS。运行时,init 会说明这一点;模拟交易结果也会计入这笔费用,因此与 live 交易的成本一致。开始 live 交易前,账户需先从自己的钱包批准一次该费用(npx @r2rlabs/reins approve-builder);在完成批准前,服务会拒绝以 live 模式启动,并说明如何批准。Testnet 订单不收取费用。

接入机器人(HTTP)

不支持 MCP 的机器人——Python、Go、Rust,或任何能发出 HTTP 请求的程序——也能使用同样的限制和决策日志:

npx @r2rlabs/reins http --port 8787        # prints a token; paper by default
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8787/limits
curl -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" \
  -d '{"symbol":"ETH","side":"buy","sizeUsd":1000,"stopLoss":2620,"reason":"Breakout retest"}' \
  http://127.0.0.1:8787/orders
路由功能
GET /health返回模拟或 live 模式及路由信息。唯一无需令牌的路由
GET /limits返回限制、剩余空间,以及每日亏损是否已触发交易暂停
GET /positions返回敞口、账户价值、止损单和任何未受保护的仓位
GET /book?symbol=ETH&depth=5返回最优盘口
GET /candles?symbol=ETH&interval=1h&count=24返回价格历史及平均波动区间
GET /decisions?limit=10返回决策日志,按时间从新到旧排列
POST /orders下单。与 Agent 一样,必须提供 reason
POST /stops设置或移动止损单
POST /cancel按 ID 取消挂单
POST /close平仓

每个路由都运行相同的风险引擎,并写入与 MCP 工具相同的记录。因此,被拒绝的订单会返回 400,并说明触发限制的原因: BLOCKED (TRADE_RISK_TOO_LARGE): Stopping out would lose $50.99, over the $30 allowed on one trade.

这是一个交易接口。 除非通过 --host 指定其他地址,否则它会绑定到 127.0.0.1;除 /health 外,每个路由都需要 bearer token。若要在本机之外开放接口,你需要自行选择令牌,并在接口前配置 TLS。

使用 Python

大多数 Hyperliquid 机器人都使用 Python,因此我们提供了客户端,而不只是代码片段:

pip install reins-client
from reins import Reins, Refused

reins = Reins.from_env()                 # REINS_URL, REINS_HTTP_TOKEN
book = reins.book("BTC")
entry, stop = book["bestAsk"], book["bestBid"] * 0.99

try:
    reins.place_order(
        symbol="BTC",
        side="buy",
        size_usd=Reins.size_for_risk(entry, stop, risk_usd=25),
        price=entry,
        stop_loss=stop,
        reason="range low held on the hourly",
    )
except Refused as refusal:
    print(refusal.code, refusal.reason)  # e.g. TRADE_RISK_TOO_LARGE

收到拒绝并不代表代码出错——这是 Reins 正常发挥作用的表现——因此拒绝会以包含代码的 Refused 形式返回,机器人可据此分支处理。 size_for_risk() 使用与风险引擎相同的计算方式,因此可以将订单规模控制在单笔交易限制内,而不是等到订单被拒绝。无需依赖项:clients/python 只有一个标准库文件;如果不想添加软件包,也可以直接将其纳入项目。

也可以完全不使用客户端,仅用 40 行纯 Python 代码: examples/bot.py。

使用真实交易验证

单元测试证明,Reins 签名的内容与 Hyperliquid 自己的 SDK 签名一致。但它们无法证明 Hyperliquid 会接受这些签名。reins live-check 会在真实账户上进行验证:

REINS_ACCOUNT_ADDRESS=0x… npx @r2rlabs/reins live-check             # reads only, free
REINS_ACCOUNT_ADDRESS=0x… REINS_PRIVATE_KEY=0x… \
  npx @r2rlabs/reins live-check --trade --size-usd 12               # a few cents in fees

读取操作会检查账户、市场、未平仓订单,以及账户是否已批准 Reins 的构建者费用。使用 --trade 时,它会使用平台允许的最小持仓规模,走完完整的下单流程:提交一个附带止损的只挂单订单、取消该订单、以市价入场、设置并调整止损、平仓,然后扫描是否还有未平仓订单。它会在首次收到与 Reins 预期不符的响应时停止,并打印实际返回的内容,因此失败时会指出具体步骤,而不必让你猜测。测试金额上限为 $100,挂单价格与市价相差 3%,因此检查运行期间不会成交。持仓期间,它还会重新读取账户价值,以捕捉因账户模式导致的权益读取错误。在主网的 Manual 账户和 Unified 账户上,这 12 个步骤都已通过。

用法
npx @r2rlabs/reins stats              # the last 30 days
npx @r2rlabs/reins stats --days 365 --json

Hyperliquid 会在 UTC 日结束后,将所有带有构建者代码的成交记录发布到每日文件中。stats 会读取 Reins 构建者地址对应的文件,并报告账户数(以及每日新增账户数)、交易量、成交额、赚取的费用、做市成交、触发的止损和最活跃的市场。它还会显示 Hyperliquid 累计记入构建者账户的费用总额;该数据来自 API,因此不会延迟:某天的文件可能要到当天结束一天或更久之后才会发布。Reins 本身不会向外发送任何数据,因此这仅适用于主网实时交易:模拟运行不会留下任何记录。

批准费用
npx @r2rlabs/reins approve-builder              # from a clone: node dist/bin/cli.js approve-builder
npx @r2rlabs/reins approve-builder --check 0x…  # what a wallet has approved

批准必须由用户的主钱包签名,因此 Reins 不会索要该钱包的密钥。approve-builder 会在 127.0.0.1 上通过随机路径提供一个页面,用户在浏览器钱包(MetaMask 或类似钱包)中对 EIP-712 批准进行签名,只有签名会返回给 Reins。Reins 会检查签名中指定的是否为 Reins 的构建者、请求的费率和网络、是否使用了新鲜的 nonce,以及签名恢复出的地址是否与声称签名的钱包一致,然后将其发送给 Hyperliquid,并通过 maxBuilderFee 读取批准状态。签名无需支付 Gas 费。--max-fee 可批准高于默认 2 bp 的上限;--network testnet 则会在测试网上批准。

我们已通过 Hyperliquid 本身验证签名:一个临时密钥的批准请求发送到测试网后,仅因没有存款而被拒绝,错误信息准确指出了该临时地址——这表明签名恢复正确,包括在使用浏览器钱包时以 Arbitrum 的链 ID 签名的情况。

或者,手动将 MCP 客户端连接到它:

{
  "mcpServers": {
    "reins": {
      "command": "node",
      "args": ["/absolute/path/to/hyperliquid-agent/dist/bin/serve.js"],
      "env": {
        "REINS_NETWORK": "testnet",
        "REINS_SYMBOLS": "BTC,ETH",
        "REINS_MAX_POSITION_USD": "5000",
        "REINS_DAILY_LOSS_USD": "500",
        "REINS_MAX_LEVERAGE": "3",
        "REINS_MAX_ORDERS_PER_MIN": "12",
        "REINS_LOG_FILE": "./decisions.jsonl"
      }
    }
  }
}

必须设置 REINS_SYMBOLS、REINS_MAX_POSITION_USD 和 REINS_DAILY_LOSS_USD——对于“这个工具最多可以亏掉你多少钱”,没有默认值。

在接入签名器之前,服务会以只读模式运行:读取操作可用,交易操作会报错。启动时会在 stderr 中说明这一点。

关于签名

L1 操作会经过 msgpack 哈希,生成一个“幻影 Agent”,并使用 EIP-712 签名。 Hyperliquid 的文档警告不要手动实现这一过程,这个警告确有道理:msgpack 会保留映射键的顺序,因此键顺序也是哈希的一部分。 调换操作中的两个字段,签名就会悄无声息地失效,而且拒绝原因中不会指出是顺序导致的。

src/signing.ts 将该方案实现为一组不持有任何密钥材料的纯函数,因此可以进行验证。src/signing.test.ts 使用 Python SDK 自带的 signing_test.py 中发布的测试向量进行验证——相同的密钥、操作和 nonce,在主网和测试网上生成逐字节相同的 r、s 和 v。这比“某种顺序曾经成功过一次”更有保障。

以下是容易出错的地方,均已由测试覆盖:

  • msgpack 键顺序是哈希的一部分——有一项测试会调换两个键并验证哈希随之改变
  • nonce 是追加到打包后操作末尾的 8 个大端字节
  • 指定金库地址时会添加 0x01 标记和 20 个字节;不指定金库时则添加 0x00
  • 主网上的 source 为 "a",测试网上为 "b"——错误的值也能正常完成签名,但另一网络会拒绝该签名
  • 无论你交易的是什么,EIP-712 域都固定为 chainId 1337,并使用零地址作为验证合约

r 和 s 会以去除前导零的最短十六进制形式输出,与 Python SDK 完全一致。端到端测试也确认了这一点:发送到测试网的签名订单因 价格区间规则被拒绝;这是订单验证环节,因此只有在身份验证已通过后才会执行。

PrivateKeySigner 不会在实例上存储密钥,并覆盖了 toJSON,因此签名权限不会泄露到日志行或决策记录中。

用法

import { HyperliquidClient, RiskEngine } from "./src/index.js";

const client = new HyperliquidClient({
  network: "testnet",
  signer,
  builder: { address: "0xYOUR_BUILDER_ADDRESS", feeTenthsBps: 10 }, // 1 bp
});

const engine = new RiskEngine({
  maxPositionUsd: 25_000,
  maxLeverage: 5,
  dailyLossLimitUsd: 2_500,
  symbolAllowlist: ["BTC", "ETH"],
  maxOrdersPerMinute: 12,
});

const snapshot = await client.positionSnapshot();
const state = { ...snapshot, realizedPnlTodayUsd: todaysPnl };

const decision = engine.check({ symbol: "BTC", side: "buy", sizeUsd: 18_400 }, state);
if (!decision.allowed) throw new Error(decision.reason);

const outcome = await client.placeOrder({
  symbol: "BTC",
  side: "buy",
  size: 0.18,
  price: 102_000,
});
engine.recordOrder();

如果构造时不传入 signer,客户端将处于只读模式:市场数据可以正常使用,调用 placeOrder 则会抛出错误。

开发

npm install
npm test

设计

产品页面位于 design/,并会在项目说明中链接的 Artifact 上渲染为画布。

已根据 Hyperliquid 文档核实的 Builder 代码事实

手续费上限,永续合约成交金额的 0.1%
手续费上限,现货成交金额的 1%
手续费单位基点的十分之一——f: 10 即 1 bp
Builder 要求永续合约账户价值 ≥100 USDC,使用 standard 账户抽象
用户授权ApproveBuilderFee,由用户的主钱包签名,而不是 API 钱包
每位用户的授权数最多同时有 10 项生效
范围永续合约的买卖双方;现货仅限卖方
收款通过常规推荐奖励流程申领

安全须知

  • Agent 可以使用 get_limits 工具查看自身限制,但没有可以更改限制的工具。
  • 停牌期间,reduce-only 订单仍然有效。始终允许平仓;不允许开仓。
  • 没有私钥时,服务会以只读模式运行——市场数据可以正常使用,但无法进行交易。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。