
jev-trader market.ts 深度解析手工编码 batchUpdate 下单本地 nonce 与异步确认全实现【免费下载链接】jev-traderOne AI trade decision every Monad block. Jev on Kuru MON-USDC.项目地址: https://gitcode.com/gh_mirrors/je/jev-traderjev-trader 是一个跑在 Monad 链上的 AI 链上交易机器人AI 模型每 300ms 一个区块就在 Kuru MON-USDC 订单簿上做一次买还是卖的决策并由真实钱包下单。它的核心文件 src/market.ts 负责三件关键事手工编码 batchUpdate 下单指令、本地维护 nonce 计数器、发送后异步轮询回执确认。本文带新手完整看懂这套高频链上交易的实现思路不用深究代码细节也能抓住精髓 一、300ms 的极限预算一个区块只做两次 RPC 往返在 Monad 链上一个区块大约 300ms。机器人必须在一个区块内完成读订单簿 → AI 决策 → 下单留给网络的时间极其紧张。因此 hot path热路径上只允许发生两次 RPC 调用RPC 调用作用延迟参考eth_call读取 Kuru 订单簿报价公开 RPC 约 18mseth_sendRawTransaction发送已签名的交易收到交易哈希即返回注意路径上没有eth_estimateGas因为 Monad 按 gasLimit 计费限额只需启动时算一次、没有实时查 gas 价格使用静态的 EIP-1559 type-2 费用。这些设计正是 market.ts 中所有手工细节的由来。二、Market 类机器人和链之间的唯一通道Market 类 是整个项目与 Monad 链交互的唯一通道核心状态字段一眼就能看懂字段含义wallet交易钱包未配置私钥时为null进入模拟dry-run模式nonce本地nonce 计数器避免每笔交易前查询链上计数feeWei最近一次已知的 gas 价格base prioritygasLimit启动时估算一次的 gas 限额之后硬编码使用pendingMap在途交易哈希 → 该区块的报价信息用于异步确认启动时 init() 按顺序完成四件事拉取 Kuru 市场参数、刷新保证金余额、同步 nonce、把 gas 限额一次性估算到位。之后热循环中不再有任何准备性查询。三、手工编码 batchUpdate为什么不用 SDK 直接调Kuru 官方 SDK 用起来更省事但每次调用都会引入类型解析、参数构造等开销。为了让下单尽可能快market.ts 选择手工编码 calldata——直接用 ethers 的Interface.encodeFunctionData拼装字节码绕开 SDK 的额外处理。encode 方法 做的事情可以拆解成四步价格换算把 USDC 价格按市场精度pricePrecision放大为链上整数数量换算把 MON 数量按sizePrecision换算为链上单位分侧填数买单只填buyPrices/buySizes卖单只填sellPrices/sellSizes另一侧留空附加取消单把本区块要撤销的挂单 ID 列表带上最后一个参数postOnlytrue确保只挂单、绝不主动吃单cross。batchUpdate的完整参数结构为batchUpdate(buyPrices, buySizes, sellPrices, sellSizes, orderIdsToCancel, postOnly)一笔交易同时完成取消上一区块的挂单 挂出本区块新挂单这正是机器人每区块替换一次报价策略的落地方式。资金来自 Kuru 保证金账户Margin Account所以交易的value恒为 0。报价位置touch 内侧 1 个 tickquotePrice 方法 决定挂单挂在哪买一侧 买一价 1 tick卖一侧 卖一价 − 1 ticktick 数量可配置。全程使用整数 tick 运算保证价格能精确表示在链上如果价差太窄、往里进不去就贴着 touch 排队。这样机器人永远是挂单方赚点差而不是付点差 四、本地 nonce不查链、先签名、发出去链上交易必须携带正确的 nonce常规做法是发送前先调eth_getTransactionCount查询一次——但那会多一个 RPC 往返在 300ms 预算里是奢侈。market.ts 的做法是本地计数器自增send 方法 用内存中的this.nonce构造交易eth_sendRawTransaction成功后this.nonce失败才回查同步发送抛错时调用 resyncNonce 从链上重新读一次计数兜底修正启动时对齐一次init()阶段先执行一次resyncNonce保证起点正确。buildTx 生成的交易也是零查询风格type: 2EIP-1559、静态maxFeePerGas/maxPriorityFeePerGas、硬编码的gasLimit、链上目标地址固定为 Kuru 市场合约。整条签名→发送路径上不发生任何额外的网络调用。五、异步确认sent → placed / reverted / lost交易发出后不等回执fire-and-forget本区块立即继续下一轮。确认工作被推迟到后续区块中执行状态触发条件含义sent交易哈希已被 RPC 接受本区块发出的意图placed回执 status 成功日志中找到OrderCreated挂单生效拿到 orderIdreverted回执 status 0x0链上订单簿已穿过挂单价或要取消的单已成交lost超过 10 个区块仍无回执视为丢失并触发 nonce 重新同步pollPending每个在途交易只查一次eth_getTransactionReceipt并与当前区块的决策并行执行不占热路径parseReceipt从回执日志里解析OrderCreated新挂单 ID和OrdersCanceled被撤销的单顺便用effectiveGasPrice更新本地费用估计。注意 Monad 的计费规则按 gasLimit 而不是实际 gasUsed 收费所以无论挂单成功还是回滚gas 成本都照付约为 gasLimit × 费用价。这就是启动时 initGasLimit 会把估算值再乘 1.15 留余量的原因——限额是每小时真金白银的成本。六、启动准备保证金充值与 dry-run 模式保证金充值ensureMargin 在启动时把 Kuru 保证金账户补足到配置目标MON USDC不足才充值、等待回执之后限价单全部从保证金账户出账dry-run 模式未配置PRIVATE_KEY时wallet为nullsend 直接返回status: sim的模拟报价不签名、不发送订单簿和决策流程全部真实——新手可以零成本观察整个系统运行。相关配置项集中在 src/config.ts如QUOTE_INSIDE_TICKS、PENDING_BLOCKS、GAS_LIMIT等区块流与原始 RPC 封装在 src/chain.ts主循环在 src/trader.ts。七、离线验证不发一笔交易也能证明编码正确项目提供了 scripts/dry-encode.ts 脚本用随机钱包离线构造并签名买/卖两笔交易把 calldata 再用 Kuru ABI反向解码逐项断言——价格对齐 tick、绝不穿价、单侧只有一笔、取消列表正确、postOnlytrue、value0、type-2 交易目标正确。这是手工编码方案的安全网不花钱、不上链就能验证字节码与官方 ABI 完全一致 ✅八、小结market.ts 用手工编码 本地 nonce 异步确认三板斧把一个普通链上交易流程压缩到只剩两次 RPC 往返稳稳装进 Monad 300ms 的区块窗口。对新手而言这套模式热路径零查询、静态费用、回执后置、失败兜底回查是任何高频链上应用都值得参考的工程范式。完整事件字段与 SSE 流式接口说明可继续阅读 README.md产品设计与界面规格见 SPEC.md。【免费下载链接】jev-traderOne AI trade decision every Monad block. Jev on Kuru MON-USDC.项目地址: https://gitcode.com/gh_mirrors/je/jev-trader创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考