wagmi Tempo 角色权限查询完全指南:用token.hasRole检查 TIP-20 代币账户角色
【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi
token.hasRole是 wagmi Tempo 模块中用于检查某个地址是否持有 TIP-20 代币特定角色(如defaultAdmin、issuer、pause等)的核心只读操作。它非常适合用在权限敏感的前端场景中——例如根据用户角色动态渲染管理面板、禁用非法操作按钮,或在读取/写入合约前先做权限校验。读完本文,你将掌握Actions.token.hasRole的命令式调用、Hooks.token.useHasRole的 React 声明式用法、全部参数语义与源码级实现原理,并能直接在你的 wagmi + Tempo 应用中落地。
TIP-20 代币的角色权限模型
在 Tempo 协议中,TIP-20 代币(参见 token.hasRole 文档)内置了一套基于角色的访问控制(RBAC)模型。与简单的owner单一管理员模式不同,TIP-20 将代币管理能力拆分为多个可独立授予/撤销的角色:
| 角色值 | 典型权限语义 |
|---|---|
defaultAdmin | 默认管理员,通常拥有角色管理、合约管理类最高权限 |
pause | 暂停代币转账等操作的能力 |
unpause | 恢复代币操作的能力 |
issuer | 铸造(mint)代币等发行类能力 |
burnBlocked | 与阻止燃烧相关的黑名单/封锁权限 |
从 token.test.ts 的测试可以看出,创建代币的地址会自动成为defaultAdmin:测试先通过token.createSync创建一个测试代币,随即调用token.hasRole断言创建者持有defaultAdmin角色且返回true。这验证了"创建者即默认管理员"的角色初始化行为。
快速开始:命令式调用Actions.token.hasRole
token.hasRole是一个**只读(read-only)**操作,不会产生交易、不需要签名,直接对链上状态发起查询。基础用法如下(对应文档中的 example.ts):
import { Actions } from 'wagmi/tempo' import { config } from './config' const hasRole = await Actions.token.hasRole(config, { account: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb', role: 'issuer', token: '0x20c0000000000000000000000000000000000011', }) console.log('Has issuer role:', hasRole) // @log: Has issuer role: true调用返回一个布尔值:true表示该地址持有指定角色,false表示不持有。
所需的 config 配置
示例中的config是标准 wagmi 配置,只需接入 Tempo 链与tempoWallet连接器即可(见 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(), }, })其中multiInjectedProviderDiscovery: false用于关闭多注入钱包探测,保证只使用显式配置的tempoWallet连接器;http()则提供 Tempo 链的 JSON-RPC 传输层。
参数详解
hasRole接收三个必填业务参数,并可选传入chainId(由ChainIdParameter提供,见源码):
account
- 类型:
Address - 含义:要检查角色的账户地址,即"谁"持有角色。例如
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb'。通常是当前连接的钱包地址,也可以是任意待校验的地址。
role
- 类型:
"defaultAdmin" | "pause" | "unpause" | "issuer" | "burnBlocked" - 含义:要检查的具体角色名,必须是上述五个内置角色之一。角色值需与
grantRoles/revokeRoles等操作中使用的角色字符串完全一致,否则查询结果没有意义。
token
- 类型:
Address | bigint - 含义:TIP-20 代币的地址或 ID。这意味着除了按合约地址查询外,该操作同样支持按代币 ID(
bigint)查询,适用于以 ID 标识代币的场合。
chainId(可选)
在源码 token.ts 中,hasRole的Parameters类型由ChainIdParameter<config> & Actions.token.hasRole.Parameters组合而成。函数体首先解构出chainId,其余参数透传给底层客户端:
export function hasRole<config extends Config>( config: config, parameters: hasRole.Parameters<config>, ): Promise<hasRole.ReturnValue> { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) return Actions.token.hasRole(client, rest) }因此,如果未显式传入chainId,将使用当前配置激活的链;在多链场景下可通过chainId指定查询目标链。
返回值
hasRole的返回类型非常简洁:
type ReturnType = boolean // Whether the account has the roletrue:该地址持有对应角色;false:该地址不持有对应角色(或代币/角色/地址组合不匹配)。
由于这是只读查询,返回值直接来自链上状态读取,不会触发交易、消耗 Gas 或要求用户签名。
源码实现原理
Actions.token.hasRole在 packages/core/src/tempo/actions/token.ts 中实现,本质上是 wagmi 对 viem Tempo 模块Actions.token.hasRole(对应 viem 官方文档)的封装:
- 客户端解析:通过
config.getClient({ chainId })获取指定链的 viem Client; - 调用透传:将
account、role、token等参数原样转发给 viem 的底层实现完成链上调用; - 类型对齐:
ReturnValue直接复用Actions.token.hasRole.ReturnValue,保证类型在整条调用链上一致。
此外,同文件还提供了查询基础设施,使其可以直接接入 TanStack Query:
queryKey(parameters):返回['hasRole', parameters]作为缓存键,参数变化即自动重新请求;queryOptions(config, parameters):构造标准 query 选项,其中enabled被设置为Boolean(rest.token && rest.role && rest.account && (query?.enabled ?? true))——即token、role、account三个参数缺一不可,任一缺失查询都不会自动执行;queryFn内部解构 queryKey 并调用hasRole(config, parameters)。
这套设计意味着token.hasRole天然具备缓存、去重、自动重取(配合watchRole等事件监听可实现实时刷新)等能力。
React 声明式用法:Hooks.token.useHasRole
在 React 应用中,更推荐使用对应 Hook(见 token.useHasRole 文档 与源码 token.ts):
import { Hooks } from 'wagmi/tempo' function App() { const { data, isLoading } = Hooks.token.useHasRole({ account: '0x...', role: 'issuer', token: '0x...', }) if (isLoading) return <div>Loading...</div> return <div>Has Role: {data ? 'Yes' : 'No'}</div> }useHasRole内部通过useConfig获取当前配置、useChainId获取激活链(未显式传chainId时自动填充),再调用上文所述的queryOptions交给useQuery执行。其类型定义继承了QueryParameter与UseQueryReturnType,因此支持select、enabled、placeholderData等标准 TanStack Query 选项,data的类型即boolean。
与角色生命周期的完整配合
hasRole通常不是孤立使用的,它与 Tempo 中其他角色管理操作共同构成完整的 RBAC 闭环,相关文档均位于 site/tempo/actions/ 目录:
- token.grantRoles:为地址授予一个或多个角色——授予后即可用
hasRole验证生效; - token.revokeRoles:撤销已授予的角色;
- token.renounceRoles:角色持有者主动放弃角色;
- token.watchRole:订阅角色变更事件,可与
hasRole结合实现权限状态的实时刷新。
典型的前端权限控制流程是:页面加载时用useHasRole查询当前账户是否具备操作所需角色 → 不具备时禁用按钮/隐藏管理入口 → 角色被授予或撤销时通过watchRole事件自动刷新查询结果,从而保证 UI 与链上权限状态始终一致。
测试验证
仓库在 token.test.ts 中为hasRole提供了两组测试,可作为实际用法的权威参考:
- 直接调用测试:连接测试连接器 →
token.createSync创建测试代币(创建者成为defaultAdmin)→ 调用token.hasRole({ token, account, role: 'defaultAdmin' })→ 断言结果为true且类型为boolean; - queryOptions 测试:用同样的参数构造
queryOptions,通过queryClient.fetchQuery(options)执行,验证查询管道返回值同样为true。
这两组测试同时印证了:返回值恒为boolean、创建者默认持有defaultAdmin、以及 query 集成路径可用。
使用注意事项
- 角色字符串必须精确匹配:
role取值仅限"defaultAdmin" | "pause" | "unpause" | "issuer" | "burnBlocked",大小写敏感,需与grantRoles等操作使用的值保持一致; - 三个参数缺一不可:由于
queryOptions中enabled要求token、role、account同时存在,使用 Hook 时若某个参数在异步加载中,查询会保持禁用状态直到参数齐全; - 只读操作无 Gas 成本:
hasRole不产生交易,可放心在渲染流程、按钮点击等场景高频调用,配合 TanStack Query 缓存避免重复请求; - 多链场景指定
chainId:当配置了多条链时,建议显式传入chainId,确保查询落在正确的链上。
总结
token.hasRole是 Tempo 代币权限体系中最小但最常用的查询原语:命令式场景用Actions.token.hasRole,React 场景用Hooks.token.useHasRole,二者共享同一套参数模型与类型定义,底层均透传至 viem 的 Tempo 实现。结合grantRoles/revokeRoles/watchRole等配套操作,你可以用最小的代码量构建出完整、实时、类型安全的代币角色权限控制界面。
【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考