news 2026/10/3 7:35:59

jev-trader 如何捕获真实成交?trades.ts 用 eth_getLogs 追踪 Maker 成交事件全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
jev-trader 如何捕获真实成交?trades.ts 用 eth_getLogs 追踪 Maker 成交事件全解析

jev-trader 如何捕获真实成交?trades.ts 用 eth_getLogs 追踪 Maker 成交事件全解析

【免费下载链接】jev-traderOne AI trade decision every Monad block. Jev on Kuru MON-USDC.项目地址: https://gitcode.com/gh_mirrors/je/jev-trader

jev-trader 是部署在 Monad 链上的 AI 交易机器人:AI 模型 Jev 每个 300ms 区块给出买/卖决策,并以 post-only 限价单挂在 Kuru MON-USDC 订单簿上。它的订单是"挂单等成交"(Maker),成交来自别人打进来,自己的交易回执里根本看不到。本文完整解析 trades.ts 如何用eth_getLogs轮询链上Trade事件,捕获每一笔真实的 Maker 成交。

为什么自己的回执里看不到成交?

传统思路是:发单 → 等eth_getTransactionReceipt→ 判断成没成交。这只适用于 Taker(主动吃单)。而 jev-trader 的每一笔单都是 post-only 挂单,成交发生在别人的 Taker 交易里:

别人的 Taker 买单打穿我们的卖单 → 成交记录在对方的交易中产生,回执与我们无关。

所以 jev-trader 换了个思路:不盯自己的交易,而是盯整条链的成交流。Kuru 订单簿合约每次撮合都会发出一个Trade事件,只要轮询这些日志,既能看到市场全部成交,也能从中挑出"打到我身上"的那些。

TradeFeed:一个类抓住全部成交

核心实现在 TradeFeed 类里,它由 trader.ts 的attachTradeFeed挂上,市场地址、RPC 地址、我们的钱包地址(maker)三个参数注入。整个捕获流程分三步。

第一步:用 topic0 锁定 Trade 事件

事件签名和预计算的 keccak256 哈希直接写在模块顶部(src/trades.ts#L20-L22):

Trade(uint40 orderId, address makerAddress, bool isBuy, uint256 price, uint96 updatedSize, address takerAddress, address txOrigin, uint96 filledSize)

注意makerAddress、takerAddress等字段全部未做索引,所以不能靠 topic 过滤"我的成交",只能把事件整体拉回来,在内存里按地址比对。

第二步:分块轮询 eth_getLogs,绕开公共节点限制

rpc.monad.xyz公共节点拒绝跨度超过 100 个区块的eth_getLogs请求,于是 poll() 做了三层防御(src/trades.ts#L44-L49):

常量值作用
FIRST_LOOKBACK300首次启动回看约 90 秒的成交热身窗口
MAX_RANGE100每次eth_getLogs最多跨 100 块,超出就切块
MAX_CATCHUP1000断线恢复时单次最多补 1000 块,防止一次性回放太多

细节很讲究:

  • 按块推进lastBlock:切块循环里每拉完一块就更新游标,中途失败也只损失当前块,下次轮询从断点续传;
  • inFlight守卫:上一次轮询还没跑完就直接丢弃新请求,绝不并发,也绝不抛异常——轮询永远不能拖垮 300ms 主循环;
  • removed: true的日志(被回滚的区块)直接跳过。

第三步:手动解码,避开"1e18 价格陷阱"

decode() 不用 SDK 而是手写解析 8 个 word:word(2)是isBuy,word(3)是价格,word(7)是成交量。

这里藏着项目注释里反复强调的坑(src/trades.ts#L9-L12):Trade.price无论市场价格精度是多少,链上都是 1e18 定点数。MON-USDC 市场的pricePrecision是 1e8,若误用会把价格缩小一亿倍;而filledSize才按sizePrecision(1e10)缩放。常量 TRADE_PRICE_DEC 固定为 18,正是为了防这个错。

💡 一箭双雕:makerAddress 同时喂两个系统

解码时做了一次地址比对(src/trades.ts#L123):makerAddress等于我们的钱包地址吗?

  • 等于→ 这是一笔我们的真实成交,连同orderId、updatedSize(剩余未成交量)一起塞进fills队列。方向还要翻转:Taker 买单(isBuy: true)打的是我们的卖单,所以记录为side: "sell";
  • 不等于→ 只是市场行情,进入 500 条环形缓冲(RING)。

同一份日志于是派生出两种价值:

  1. 给 AI 看:summary() 聚合出窗口内的成交笔数、买卖量差(CVD)、VWAP、最新价和方向,经 buildState 送入模型,成为决策的动量特征;
  2. 给自己记账:drainFills()(src/trades.ts#L158-L160)取出我们的成交,交给 harvest() 更新持仓、已实现盈亏,并通过 SSE 推给前端面板。

从日志到面板:fill 事件的完整链路

整条数据流串起来是这样的:

eth_getLogs → decode() → fills 队列 → drainFills() → harvest() → liveFills() 核对订单簿 → applyFill() 记账 → onFill() → SSE "fill" 事件 → 前端成交带

其中 liveFills() 还会用updatedSize同步订单簿状态:部分成交就更新剩余数量,全部成交(updatedSize <= 0)就摘掉这笔订单。注意轮询是挂在热路径之外的——trader.ts#L102 里poll(block).then(() => this.harvest())不阻塞本块的"读簿→决策→发单",保证 300ms 预算不被日志拉取吃掉。

🧪 没有私钥也能验证:dry run 模拟成交

没配PRIVATE_KEY时进入 dry run:订单不真正上链,但成交判定逻辑完全一样——模拟单从下一区块开始"挂"在簿上,一旦真实成交流里出现打穿其价格的打印(simFills()),就按打印数量成交,事件里标simulated: true。真实成交与模拟成交走的是同一套判定规则,这让策略在零资金下就能被完整验证。

快速上手:本地验证 trades.ts

cp .env.example .env bun install bun run scripts/trades-smoke.ts

trades-smoke.ts 会真实回看约 1000 个区块的Trade日志,打印 CVD/VWAP 汇总和最近 5 笔成交,是检验eth_getLogs分块逻辑最快的冒烟脚本。配置项集中在 src/config.ts,其中READ_RPC_URL专供日志轮询与读簿,与发单通道RPC_URL分离。更多背景见 README.md 的 Endpoints 一节。

小结

jev-trader 捕获真实成交的关键不是"盯自己的回执",而是:

  1. 换视角:轮询全链Trade日志(topic0 过滤 + 100 块分片 + 断点续传);
  2. 一次解码两用途:行情喂 AI,makerAddress命中即真实成交;
  3. 精度纪律:价格恒按 1e18 还原,数量按sizePrecision还原;
  4. 不占热路径:日志轮询与 300ms 决策循环解耦,成交晚一两块到达也不影响下一单。

这套模式对任何想做链上 Maker 策略的项目都通用:只要合约在撮合时发带 maker 地址的事件,eth_getLogs就是捕获真实成交最可靠、也最便宜的路径。

【免费下载链接】jev-traderOne AI trade decision every Monad block. Jev on Kuru MON-USDC.项目地址: https://gitcode.com/gh_mirrors/je/jev-trader

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 7:35:40

语音合成TTS项目:自然度、情感和实时部署怎么兼得

摘要:一篇能直接复用的项目实战 这是一篇可以直接照着做的语音与音频长文项目实战。项目面向“有声内容、客服播报、导航提示和无障碍阅读”,核心方法是“声学模型、声码器、音素对齐、时长预测、情感控制”,技术栈以Python、VITS、Coqui TTS、PyTorch、ONNX、FastAPI为主。…

作者头像 李华
网站建设 2026/10/3 7:35:21

《FastAPI + SQLAlchemy异步实战(二):构建用户接口》

《FastAPI SQLAlchemy异步实战&#xff08;二&#xff09;&#xff1a;构建用户接口》此部分讲解对用户功能接口的讲解&#xff0c;相信对于大部分后端项目来说&#xff0c;用户功能相关接口一定都是必不可少的&#xff0c;相较于新闻接口这部分难度更大&#xff0c;涉及用户注…

作者头像 李华
网站建设 2026/10/3 7:34:51

大模型知识库项目:数据治理、向量库和权限系统怎么做

摘要:一篇能直接复用的项目实战 这是一篇可以直接照着做的大模型与智能体长文项目实战。项目面向“跨部门知识共享、研发文档检索和合规制度查询”,核心方法是“元数据过滤、增量索引、权限感知检索、去重聚类、引用链路”,技术栈以Python、PostgreSQL、Milvus、Redis、Min…

作者头像 李华
网站建设 2026/10/3 7:33:48

Vibe-Research 每日复盘与资讯雷达:一站式盯住 A 股热点信号

Vibe-Research 每日复盘与资讯雷达&#xff1a;一站式盯住 A 股热点信号 【免费下载链接】Vibe-Research Vibe-Research: Your Personal Trading Research Agent A股/美股/港股 的个人投研 Agent&#xff1a;每日复盘、资讯雷达、个股数据、板块中心、我的持仓、研究记录、回测…

作者头像 李华
网站建设 2026/10/3 7:33:44

单视频三维实时重构支撑海岸带地形、岸线、滩涂三维重建

单视频三维实时重构支撑海岸带地形、岸线、滩涂三维重建一、方案背景我国海岸带涵盖基岩岸线、砂质滩涂、淤泥质潮间带、河口湿地等复杂地貌&#xff0c;潮涨潮落造成滩涂水陆边界动态变化&#xff0c;芦苇、灌木、礁石形成天然遮挡。海岸带管控涉及边海防巡查、岸线确权、滩涂…

作者头像 李华