ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

wagmi Tempo 链上事件监听实战:`policy.watchCreate` 监听策略创建事件的完整指南

wagmi Tempo 链上事件监听实战:`policy.watchCreate` 监听策略创建事件的完整指南 wagmi Tempo 链上事件监听实战policy.watchCreate监听策略创建事件的完整指南【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi本篇指南以 wagmi 仓库中site/tempo/actions/policy.watchCreate.md文档为核心系统讲解 Tempo 链上 TIP403 策略Policy注册表中策略创建事件的实时监听方案。你将掌握Actions.policy.watchCreate的调用方式、完整参数语义、底层实现原理以及如何在 React 应用中通过Hooks.policy.useWatchCreate声明式监听并能结合仓库源码与测试用例验证监听行为。本文适用于需要在 Tempo 链上构建代币访问控制、合规风控或链上审计类应用的前端开发者。背景TIP403 策略注册表与事件监听的意义Tempo 链引入了一套**传输策略Transfer Policy**机制用于对 TIP-20 代币的转账进行访问控制。在site/tempo/actions/index.md中Policy Actions 被定义为Creates a new transfer policy for token access control创建用于代币访问控制的传输策略。一个策略可以是白名单类型whitelist或黑名单类型blacklist管理员可以后续修改名单、更换管理员最终通过policy.isAuthorized判断某个地址是否被授权。这些策略统一登记在TIP403 Registry策略注册表合约中。当任何账户通过policy.create/policy.createSync创建新策略时注册表会发出对应的事件。policy.watchCreate就是 wagmi 为 Tempo 提供的、监听该策略创建事件的响应式原语——它订阅事件流在每次新策略创建时回调你的处理函数。监听类 Action 在整个 Tempo Action 体系中是独立的成员与查询类policy.getData、policy.isAuthorized、写入类policy.create、policy.setAdmin、policy.modifyWhitelist、policy.modifyBlacklist形成互补让应用既能发起操作也能实时感知链上状态变化。快速上手监听策略创建事件Actions.policy.watchCreate接收config与参数对象返回一个取消订阅函数。最简用法如下取自site/tempo/actions/policy.watchCreate.md的 Usage 示例import { Actions } from wagmi/tempo import { config } from ./config const unwatch Actions.policy.watchCreate(config, { onPolicyCreated(args, log) { console.log(args:, args) }, }) // Later, stop watching unwatch()其中config需要是配置了 Tempo 链的 wagmi 配置。仓库中的模板配置site/snippets/react/config-tempo.ts给出了完整可运行版本import { 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(), }, })要点chains必须包含tempo链transports为tempo.id配置http()传输层并通过tempoWallet()注入钱包连接器。config也支持通过chainId参数显式指定要监听的链默认使用配置中的链。返回类型一个取消订阅函数policy.watchCreate的返回类型为() void。它返回一个用于取消订阅事件的函数。调用后事件监听立即终止。在组件卸载、页面切换或业务不再需要监听时务必调用避免内存泄漏与无效 RPC 订阅。参数详解Actions.policy.watchCreate(config, parameters)的参数对象完整语义如下。onPolicyCreated必填类型functiondeclare function onPolicyCreated(args: Args, log: Log): void type Args { /** ID of the created policy */ policyId: bigint /** Type of policy */ type: PolicyType /** Address that created the policy */ updater: Address }策略创建成功时调用。回调收到两个参数args事件解码参数。policyId为新建策略的 IDbiginttype为策略类型PolicyTypeupdater为创建策略的地址Address。log对应的原始事件日志对象可用于获取区块号、交易哈希等链上元信息。PolicyType的取值可以从仓库测试中得到印证在packages/core/src/tempo/actions/policy.test.ts中createSync以type: whitelist创建时返回policyType: 0以type: blacklist创建时返回policyType: 1而getData校验的结果data.type分别为whitelist与blacklist。args可选类型objecttype Args { /** Filter by policy ID */ policyId?: bigint | bigint[] | null /** Filter by updater address */ updater?: Address | Address[] | null }可选过滤参数用于缩小监听范围policyId按策略 ID 过滤可传单个bigint或bigint[]。例如只关心某个特定策略是否被创建注意创建事件产生的是新 ID实际更常用于配合特定地址过滤。updater按创建者地址过滤可传单个Address或Address[]。例如只监听当前用户或某组受信任地址发起的策略创建。fromBlock可选类型bigint开始监听的起始区块。传入后将从该区块起扫描事件含历史事件回放不传则从最新区块开始监听。onError可选类型functiondeclare function onError(error: Error): void当获取新区块时发生错误所调用的回调。订阅在运行期间可能因网络抖动、RPC 异常等原因出错可通过该回调捕获Error并做日志记录或告警。poll可选类型true启用轮询模式。默认情况下监听基于订阅推送若你的环境如某些不支持订阅的 RPC 端点需要轮询可传入poll: true。pollingInterval可选类型number轮询频率毫秒。仅在启用轮询模式时生效未显式传入时默认使用Client的pollingInterval配置。源码级实现从 wagmi 到 viem 的委托调用链policy.watchCreate并不是重新实现的事件订阅逻辑而是对底层viem/tempoAction 的类型安全封装。核心实现位于packages/core/src/tempo/actions/policy.ts的watchCreate函数export function watchCreateconfig extends Config( config: config, parameters: watchCreate.Parametersconfig, ) { const { chainId, ...rest } parameters const client config.getClient({ chainId }) return Actions.policy.watchCreate(client, rest) } export declare namespace watchCreate { export type Parametersconfig extends Config ChainIdParameterconfig Actions.policy.watchCreate.Parameters }调用链可以概括为三层参数拆分从参数中解构出chainId其余参数onPolicyCreated、args、fromBlock、onError、poll、pollingInterval等原样透传。客户端获取通过config.getClient({ chainId })取得对应链的 viem 客户端——这与查询类 Action如getData、isAuthorized使用config.getClient一致而写入类 Actioncreate、setAdmin则使用getConnectorClient获取连接器客户端因为写入需要钱包签名。委托底层将客户端与参数一并交给Actions.policy.watchCreate(client, rest)执行真实的事件监听并把返回的取消订阅函数直接返回给调用方。Parameters类型通过交叉类型合并了ChainIdParameter可显式指定chainId与 viem 底层的Actions.policy.watchCreate.Parameters保证类型提示与底层完全对齐。这也解释了为何原文档在Viem一节标注了policy.watchCreate的 viem 对应关系wagmi 的 Tempo Actions 本质上是 viem Tempo Actions 的配置感知封装。测试验证监听行为如何被确认仓库在packages/core/src/tempo/actions/policy.test.ts中为watchCreate编写了端到端测试可以直接印证文档描述的行为describe(watchCreate, () { test(default, async () { await connect(config, { connector: config.connectors[0]!, }) const events: any[] [] const unwatch policy.watchCreate(config, { onPolicyCreated: (args, log) { events.push({ args, log }) }, }) // create policy await policy.createSync(config, { type: whitelist, }) await vi.waitFor(() { expect(events.length).toBeGreaterThanOrEqual(1) }) unwatch() expect(events[0].args.policyId).toBeDefined() expect(events[0].args.updater).toBe(account.address) expect(events[0].args.type).toBe(whitelist) }) })该测试完整还原了先订阅、再触发、后断言的标准流程先connect连接config.connectors[0]对应的测试账户调用watchCreate注册onPolicyCreated回调将事件推入events数组通过createSync实际创建一条whitelist类型策略触发注册表事件用vi.waitFor等待事件到达断言args.policyId已定义、args.updater为发起创建的交易账户地址、args.type为whitelist最后调用unwatch()取消订阅。这组断言与文档中Args的三个字段policyId、type、updater一一对应是理解事件负载的最佳范例。同一测试文件中watchAdminUpdated、watchWhitelistUpdated、watchBlacklistUpdated的测试采用了相同的模式说明watch 系列Action 的参数与行为约定完全一致。React 集成Hooks.policy.useWatchCreate声明式监听在 React 应用中无需手动管理unwatch可直接使用Hooks.policy.useWatchCreate。其实现位于packages/react/src/tempo/hooks/policy.tsimport { Hooks } from wagmi/tempo function App() { Hooks.policy.useWatchCreate({ onPolicyCreated(args) { console.log(Policy created:, args) }, }) return divWatching for policy creation.../div }Hook 内部通过useEffect封装了完整的订阅生命周期export function useWatchCreate config extends Config ResolvedRegister[config], (parameters: useWatchCreate.Parametersconfig {}) { const { enabled true, onPolicyCreated, ...rest } parameters const config useConfig({ config: parameters.config }) const configChainId useChainId({ config }) const chainId parameters.chainId ?? configChainId useEffect(() { if (!enabled) return if (!onPolicyCreated) return return Actions.policy.watchCreate(config, { ...rest, chainId, onPolicyCreated, }) }, [ config, enabled, chainId, onPolicyCreated, rest.fromBlock, rest.onError, rest.poll, rest.pollingInterval, ]) }值得注意的设计细节自动清理useEffect的清理函数正是Actions.policy.watchCreate返回的unwatch组件卸载时自动取消订阅enabled开关额外提供的enabled?: boolean参数默认true置为false时可暂停监听而不卸载组件响应式依赖chainId默认取自useChainId链切换时自动重订阅fromBlock、onError、poll、pollingInterval等参数变化同样会触发重建订阅config透传可通过parameters.config覆盖默认的 wagmi 配置。Hook 的参数类型useWatchCreate.Parameters是Actions.policy.watchCreate.Parameters的 ExactPartial 版本并额外合并了ConfigParameter与enabled因此核心参数语义与命令式版本完全一致。与策略生命周期其他 Action 的配合watchCreate不是孤立存在的它是策略生命周期管理的一部分。完整的 Policy Actions 清单见site/tempo/actions/index.md以下是与事件监听最常配合的相邻 ActionAction作用配合场景policy.create/createSync创建传输策略触发watchCreate事件的来源policy.getData读取策略数据管理员、类型收到创建事件后用policyId反查策略详情policy.isAuthorized判断地址是否被策略授权事件驱动的权限校验policy.setAdmin更换策略管理员配合watchAdminUpdated监控管理变更policy.modifyWhitelist修改白名单配合watchWhitelistUpdated监控名单变更policy.modifyBlacklist修改黑名单配合watchBlacklistUpdated监控名单变更一个典型的实战组合是监听watchCreate获得policyId→ 调用getData获取策略类型与管理员 → 通过isAuthorized判断某个用户是否受该策略约束。另外注意isAuthorized存在两个特殊策略 ID见packages/core/src/tempo/actions/policy.test.tspolicyId 0n为永远拒绝、policyId 1n为永远允许在业务逻辑中可作为特殊分支处理。最佳实践与注意事项及时取消订阅命令式用法务必在不需要时调用返回的unwatch()React 用法由 Hook 自动处理但要注意enabled与依赖数组的配合。按需过滤事件量大时优先使用argspolicyId/updater过滤减少无效回调与网络负载。轮询 vs 订阅默认订阅模式实时性最好RPC 不支持订阅或需要兼容性时启用poll: true并合理设置pollingInterval未设置时沿用 Client 的pollingInterval配置。错误处理订阅期间区块拉取可能出错通过onError捕获并记录避免静默失败。历史回放需要补偿缺失事件时使用fromBlock从指定区块开始监听可结合最新区块号回溯补全。事件与交易联动watchCreate回调中的log对象可用于关联交易哈希、区块高度与createSync返回的receipt相互印证。延伸阅读本文核心参考policy.watchCreate官方文档Tempo Actions 总览含全部 Policy/Token/DEX 等 Actionsite/tempo/actions/index.md底层实现packages/core/src/tempo/actions/policy.ts端到端测试packages/core/src/tempo/actions/policy.test.tsReact Hook 实现packages/react/src/tempo/hooks/policy.tsTempo 配置模板site/snippets/react/config-tempo.ts【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进