wagmi Tempo `dex.useWatchOrderPlaced` Hook 实战:监听 Stablecoin DEX 挂单事件

wagmi Tempo `dex.useWatchOrderPlaced` Hook 实战:监听 Stablecoin DEX 挂单事件 wagmi Tempodex.useWatchOrderPlacedHook 实战监听 Stablecoin DEX 挂单事件【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmidex.useWatchOrderPlaced是 wagmi Tempo 模块为 React 应用提供的声明式 Hook用于在 Stablecoin DEX 上实时监听订单已挂出Order Placed事件。本文以该 Hook 的官方文档为核心结合 packages/react/src/tempo/hooks/dex.ts、packages/core/src/tempo/actions/dex.ts 及对应测试源码完整讲解它的用法、参数、事件回调结构与底层实现原理帮助你在组件中像订阅普通状态一样订阅链上挂单事件。为什么需要dex.useWatchOrderPlaced在去中心化交易所DEX中挂单place order是最核心的用户行为之一。构建订单簿类 UI如实时行情、成交提示、订单流看板时前端需要第一时间感知新订单已挂出这一链上事件。wagmi Tempo 将这一能力封装成两层 API命令式 Actiondex.watchOrderPlaced直接调用并手动管理退订声明式 Hookdex.useWatchOrderPlaced在 React 组件中自动订阅、自动清理与WagmiProvider的配置体系天然打通。Hook 的核心价值在于以 React 的方式做链上事件订阅你只需要声明我要监听什么订阅生命周期挂载时开始、卸载时结束由 Hook 内部通过useEffect管理无需手写退订逻辑。基本用法最小示例在组件中调用Hooks.dex.useWatchOrderPlaced并传入onOrderPlaced回调即可开始监听import { Hooks } from wagmi/tempo function App() { Hooks.dex.useWatchOrderPlaced({ onOrderPlaced: (args, log) { console.log(args:, args) }, }) return divWatching for order placements.../div }该用法与官方文档示例一致见 site/tempo/hooks/dex.useWatchOrderPlaced.md。onOrderPlaced回调会收到两个参数args解析后的事件参数对象与log原始事件日志。组件级监听的正确姿势Hook 通常应在组件内部使用而非模块顶层因为它的订阅生命周期绑定组件挂载/卸载import { Hooks } from wagmi/tempo export function OrderFeed() { const [orders, setOrders] useStateArgs[]([]) Hooks.dex.useWatchOrderPlaced({ onOrderPlaced(args) { setOrders((prev) [...prev, args]) }, }) return ul{orders.map((o, i) li key{i}{String(o.amount)}/li)}/ul }注意在onOrderPlaced中直接调用setState更新状态即可驱动 UI 刷新这正是声明式 Hook 相比命令式 Action 的便捷之处。需要的配置环境Tempo 相关 Hook 依赖一个配置了tempo链与tempoWallet连接器的 wagmiConfig并通过WagmiProvider注入。官方文档代码组中引用的配置文件如下site/snippets/react/config-tempo.tsimport { createConfig, http } from wagmi import { tempo } from wagmi/chains import { tempoWallet } from wagmi/tempo export const config createConfig({ connectors: [tempoWallet()], chains: [tempo], multiInjectedProviderDiscovery: false, transports: { [tempo.id]: http(), }, })然后在应用根部用WagmiProvider提供该配置Hook 即可从最近的 Provider 中自动获取config。参数详解dex.useWatchOrderPlaced的参数类型定义如下packages/react/src/tempo/hooks/dex.tstype Parametersconfig ExactPartialActions.dex.watchOrderPlaced.Parametersconfig ConfigParameterconfig { enabled?: boolean | undefined }即底层 Action 的全部参数全部可选 可选的config Hook 特有的enabled开关。config类型Config | undefined作用指定要使用的 wagmiConfig即 createConfig 创建的配置替代从最近的WagmiProvider中获取。一般情况下无需传该参数只有在需要绕开 Provider 上下文、显式指定配置时才使用。enabledHook 独有类型boolean默认true这是 Hook 层特有的开关。当enabled为false时Hook 不会发起订阅。从实现看packages/react/src/tempo/hooks/dex.tsconst { enabled true, onOrderPlaced, ...rest } parameters ... useEffect(() { if (!enabled) return if (!onOrderPlaced) return return Actions.dex.watchOrderPlaced(config, { ...rest, chainId, onOrderPlaced, }) }, [...])enabled用于条件订阅场景例如仅在用户已连接钱包或某个交易对处于激活状态时才开启监听。onOrderPlaced必传回调类型(args: Args, log: Log) void挂单事件触发时被调用的回调。官方文档site/tempo/actions/dex.watchOrderPlaced.md给出了完整的Args结构type Args { /** ID of the placed order */ orderId: bigint /** Address that placed the order */ maker: Address /** Address of the base token */ token: Address /** Amount of tokens in the order */ amount: bigint /** Whether this is a buy order */ isBid: boolean /** Price tick for the order */ tick: number }各字段含义字段类型说明orderIdbigint被挂出的订单 IDmakerAddress挂单者的地址tokenAddress基础代币地址amountbigint订单中的代币数量isBidboolean是否为买单true 为买false 为卖ticknumber订单的价格 tick注意amount与orderId为bigint类型直接进行字符串拼接会得到十进制大整数表示建议使用BigInt相关的格式化工具如formatUnits处理展示。过滤参数args、maker、tokenHook 支持按订单 ID、maker 地址、token 地址过滤事件避免无关事件触发回调args可选object订阅过滤器对象包含三个可选字段orderId?: bigint | bigint[] | null—— 按订单 ID 过滤maker?: Address | Address[] | null—— 按挂单地址过滤token?: Address | Address[] | null—— 按代币地址过滤maker可选Address单独传入时等价于按 maker 地址过滤事件token可选Address单独传入时等价于按 token 地址过滤事件。args过滤器与单独的maker/token参数在类型上均映射到底层 Action 的过滤配置见 packages/core/src/tempo/actions/dex.ts 中watchOrderPlaced.Parameters对 viem 参数的透传可传入数组实现多值匹配。fromBlock可选类型bigint作用指定开始监听的区块高度用于从历史区块起回放事件例如页面刷新后补全错过的挂单记录。轮询相关poll与pollingIntervalpoll可选类型固定为true开启轮询模式默认采用订阅模式即通过链的过滤器推送事件pollingInterval可选类型为number轮询频率毫秒未指定时默认使用 Client 的pollingInterval配置。在无法使用 WebSocket 订阅推送的环境如某些 HTTP RPC 场景下可通过poll: true降级为定时拉取。onError可选类型(error: Error) void作用当获取新区块/新事件出错时调用例如网络抖动或 RPC 不可用可用于错误上报或 UI 提示。chainId可选虽然官方文档参数列表未单独列出但从实现packages/react/src/tempo/hooks/dex.ts可以看到 Hook 内部通过useConfig与useChainId解析链 IDconst config useConfig({ config: parameters.config }) const configChainId useChainId({ config }) const chainId parameters.chainId ?? configChainId即未显式传入chainId时默认使用当前 Provider 所激活的链。底层原理Hook 如何桥接 Actiondex.useWatchOrderPlaced的实现非常精简——它本质上是命令式 Action 的 React 封装。调用链为useWatchOrderPlaced (React Hook) └─ Actions.dex.watchOrderPlaced(config, parameters) // wagmi/core Action └─ config.getClient({ chainId }) // 获取链客户端 └─ viem Actions.dex.watchOrderPlaced(client, rest) // 底层链交互对应源码packages/react/src/tempo/hooks/dex.ts 与 packages/core/src/tempo/actions/dex.ts// React 层useEffect 内调用 Action 并返回退订函数 useEffect(() { if (!enabled) return if (!onOrderPlaced) return return Actions.dex.watchOrderPlaced(config, { ...rest, chainId, onOrderPlaced, }) }, [config, enabled, chainId, onOrderPlaced, rest.fromBlock, ...]) // Core 层解析出 chainId 对应的 client 后转发给 viem export function watchOrderPlacedconfig extends Config( config: config, parameters: watchOrderPlaced.Parametersconfig, ) { const { chainId, ...rest } parameters const client config.getClient({ chainId }) return Actions.dex.watchOrderPlaced(client, rest) }几个值得注意的实现细节退订即清理Actions.dex.watchOrderPlaced返回一个() void的退订函数官方文档 Return Type 亦标注为() voidHook 将其作为useEffect的清理函数返回因此组件卸载时订阅会被自动取消不会造成内存泄漏。依赖数组精确控制重订阅useEffect的依赖数组显式列出了rest.fromBlock、rest.maker、rest.onError、rest.poll、rest.pollingInterval、rest.token等参数。当这些参数变化时旧订阅会被取消并重新建立onOrderPlaced也在依赖中确保回调引用更新后立即生效。enabled前置短路enabled false或未传onOrderPlaced时直接不建立订阅避免无效的链上连接。测试验证过滤与事件数据完整性仓库中的测试packages/react/src/tempo/hooks/dex.test.ts从两个维度验证了该 Hook 的行为默认监听default先渲染 Hook再通过Actions.dex.placeSync依次挂出买单与卖单随后用vi.waitUntil(() events.length 2)等待两个事件到达并断言expect(events[0]?.isBid).toBe(true) expect(events[0]?.amount).toBe(parseUnits(100, 6)) expect(events[1]?.isBid).toBe(false) expect(events[1]?.amount).toBe(parseUnits(100, 6))即买单事件isBid为true、卖单事件isBid为false且amount精确等于挂单时解析后的数量验证了事件数据的完整性与方向标记的正确性。按 token 过滤filter by token为 Hook 传入token: base过滤器同时在base与另一个交易对base2上分别挂单只有匹配base的事件被回调捕获验证过滤参数确实生效。与 Action 的关系何时用 Hook、何时用 Action官方文档在 Hook 文档末尾列出了两个关联 Actiondex.place挂单 Action与watchOrderPlaced形成写-读配对——dex.place产生挂单事件useWatchOrderPlaced消费该事件dex.watchOrderPlaced命令式事件监听 ActionuseWatchOrderPlaced的底层实现。选择建议在 React 组件内需要监听挂单事件、且希望自动管理订阅生命周期首选Hooks.dex.useWatchOrderPlaced在组件外如事件总线、服务端逻辑、非 React 上下文需要监听或需要手动控制退订时机使用Actions.dex.watchOrderPlaced(config, { onOrderPlaced })并保存其返回的退订函数。命令式版本的典型用法见 site/tempo/actions/dex.watchOrderPlaced.mdimport { Actions } from wagmi/tempo import { config } from ./config const unwatch Actions.dex.watchOrderPlaced(config, { onOrderPlaced(args, log) { console.log(args:, args) }, }) // Later, stop watching unwatch()实战示例带过滤的订单流看板综合以上知识点一个监听指定交易对买单/卖单的完整组件如下import { useMemo, useState } from react import { Hooks } from wagmi/tempo import { formatUnits } from viem type OrderEvent { orderId: bigint maker: 0x${string} token: 0x${string} amount: bigint isBid: boolean tick: number } export function OrderBookFeed({ token }: { token: 0x${string} }) { const [orders, setOrders] useStateOrderEvent[]([]) const [error, setError] useStateError | null(null) Hooks.dex.useWatchOrderPlaced({ token, // 只监听该交易对的挂单 enabled: Boolean(token), fromBlock: undefined, // 默认从当前区块开始 onOrderPlaced(args) { setOrders((prev) [args, ...prev].slice(0, 50)) }, onError(err) { setError(err) }, }) const bids useMemo(() orders.filter((o) o.isBid), [orders]) const asks useMemo(() orders.filter((o) !o.isBid), [orders]) return ( div {error p style{{ color: red }}{error.message}/p} h3买单{bids.length}/h3 ul{bids.map((o) li key{String(o.orderId)}{formatUnits(o.amount, 6)} tick {o.tick}/li)}/ul h3卖单{asks.length}/h3 ul{asks.map((o) li key{String(o.orderId)}{formatUnits(o.amount, 6)} tick {o.tick}/li)}/ul /div ) }要点回顾用token过滤避免无关交易对事件干扰用enabled控制未传入 token 时不建立订阅在onOrderPlaced中更新 React state驱动 UI 实时刷新通过isBid区分买卖方向用formatUnits处理bigint数量展示。小结dex.useWatchOrderPlaced是 wagmi Tempo 中事件驱动 UI的代表性 Hook它以最小的心智负担一个回调 可选过滤器将 Stablecoin DEX 的挂单事件接入 React 组件底层通过useEffect桥接到wagmi/core的dex.watchOrderPlacedAction再透传到 viem 完成真实的链上事件订阅并在组件卸载时自动退订。配合dex.place挂单、token/maker过滤器与fromBlock历史回放你可以快速构建订单流看板、成交提示、实时行情等去中心化交易应用的核心功能。进一步阅读Tempo Hooks 总览、dex.placeAction、dex.watchOrderPlacedAction。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考