Watch Token Roles
token.watchRole
Watches TIP-20 RoleMembershipUpdated events for a token. The event is emitted when a role is granted to, or revoked from, an account. Learn more about roles
Usage
import { } from './viem.config'
const = ..({
: '0x20c0000000000000000000000000000000000000',
})
.(() => {
for (const of ) .(.)
{ role: '0x114e74f6ea3bd819998f78687bfcb11b140da08e9b7d222fa9c1f1ba1f2aa122', account: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', sender: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', hasRole: true}
})
// Later, tear down the watcher.
.()import { , } from 'viem/tempo'
export const = .({
: .('0x...'),
})Also callable standalone: Actions.token.watchRole(client, options), with Actions imported from 'viem/tempo'.
Recipes
Alert on Unexpected issuer Grants
Filter args.role with TokenRole.serialize and page an operator when the issuer role is granted to an account outside your allowlist.
import { } from 'viem/tempo'
import { } from './viem.config'
// Accounts authorized to hold the issuer role.
const = new <string>([
'0x8ba1f109551bD432803012645Ac136ddd64DBA72',
])
const = ..({
: { : .('issuer') },
: '0x20c0000000000000000000000000000000000000',
})
.(() => {
for (const of ) {
if (!.. || .(..)) continue
.('Unexpected grant:', .., 'by', ..)
Unexpected grant: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 by 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
}
})import { , } from 'viem/tempo'
export const = .({
: .('0x...'),
})Pause Issuance When Your Service Loses the issuer Role
Filter args.account and args.role together to react when your own service account's issuer access is revoked, halting mint jobs before they fail onchain.
import { } from 'viem/tempo'
import { } from './viem.config'
const = ..({
: {
: ..,
: .('issuer'),
},
: '0x20c0000000000000000000000000000000000000',
})
.(() => {
for (const of ) {
// Halt issuance jobs until access is restored.
if (!..) .('Issuer role revoked by', ..)
}
})import { , } from 'viem/tempo'
export const = .({
: .('0x...'),
})Return Value
Returns a watcher handle. Watching starts when the first listener (or async iterator) attaches, and stops when off is called.
type ReturnType = {
/** Registers a log listener. Starts the watcher on first registration. Returns an unregister function. */
onLogs: (fn: (logs: readonly Log[]) => void) => () => void
/** Registers an error listener. Returns an unregister function. */
onError: (fn: (error: Error) => void) => () => void
/** Tears down the watcher: removes listeners, ends iterators, stops the poll or subscription. */
off: () => void
/** Async-iterates emitted log batches (latest-only stream). */
[Symbol.asyncIterator]: () => AsyncIterableIterator<{ logs: readonly Log[] }>
}Each log is decoded, with the event arguments on args:
type Log = {
/** Decoded `RoleMembershipUpdated` event arguments. */
args: {
/** Role that was updated (bytes32 role hash). */
role: Hex
/** Account whose membership changed. */
account: Address
/** Address that performed the update. */
sender: Address
/** Whether the account now holds the role. */
hasRole: boolean
}
/** Name of the emitted event. */
eventName: 'RoleMembershipUpdated'
// ...standard log fields (address, blockHash, blockNumber, logIndex, transactionHash, ...)
}Role values are bytes32 role hashes. Compare them against a named role (defaultAdmin, pause, unpause, issuer, burnBlocked) with TokenRole.serialize from viem/tempo.
Parameters
args
- Type:
object
type Args = {
/** Filter by role (bytes32 role hash). */
role?: Hex | Hex[] | null
/** Filter by account. */
account?: Address | Address[] | null
/** Filter by sender. */
sender?: Address | Address[] | null
}Indexed argument values to filter logs by. Derive a role hash from a named role with TokenRole.serialize from viem/tempo, for example TokenRole.serialize('issuer').
batch
- Type:
boolean - Default:
true
Whether to batch the logs found within a poll interval into a single emission. When false, each log is emitted on its own.
fromBlock
- Type:
bigint
Block number from which to start watching for logs.
poll
- Type:
boolean
Whether to poll for new logs instead of using a subscription. Defaults to true when the transport cannot subscribe or fromBlock is provided.
pollingInterval
- Type:
number - Default:
client.pollingInterval
Polling frequency (in ms).
token
- Type:
Address | bigint
Token to operate on: a TIP-20 token id or a contract address.