Skip to content
LogoLogo

Watch Token Mints

token.watchMint

Watches TIP-20 Mint events for a token.

Usage

import {  } from './viem.config'
 
const  = ..({
  : '0x20c0000000000000000000000000000000000000',
})
 
.(() => {
  for (const  of ) .(.)
{ to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', amount: 100000000n }
})
 
// Later, tear down the watcher.
.()

Also callable standalone: Actions.token.watchMint(client, options), with Actions imported from 'viem/tempo'.

Recipes

Alert on Mints Your Issuance Service Did Not Submit

Watch every mint and compare it against the transactions your issuance service submitted; a mint you did not initiate is an early signal of a compromised issuer key.

import {  } from './viem.config'
 
// Transaction hashes of mints your issuance service submitted.
const  = new <string>()
 
const  = ..({
  : '0x20c0000000000000000000000000000000000000',
})
 
.(() => {
  for (const  of ) {
    if (. && .(.)) continue
    .('Unexpected mint:', .., ..)
Unexpected mint: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 100000000n
  }
})

Credit Accounts When On-Ramp Mints Settle

Filter args.to to the customer wallets in an on-ramp batch, so each account is marked funded when its mint settles onchain.

import {  } from './viem.config'
 
const  = ..({
  : {
    : [
      '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
      '0x8ba1f109551bD432803012645Ac136ddd64DBA72',
    ],
  },
  : '0x20c0000000000000000000000000000000000000',
})
 
.(() => {
  for (const  of ) .('Funded:', .., ..)
Funded: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb 100000000n
})

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 `Mint` event arguments. */
  args: {
    /** Address that received the tokens. */
    to: Address
    /** Amount minted. */
    amount: bigint
  }
  /** Name of the emitted event. */
  eventName: 'Mint'
  // ...standard log fields (address, blockHash, blockNumber, logIndex, transactionHash, ...)
}

Parameters

args

  • Type: object
type Args = {
  /** Filter by recipient address. */
  to?: Address | Address[] | null
}

Indexed argument values to filter logs by.

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.