TokenManager is a per-token, per-domain contract that controls crosschain
transfers for a custom token registered on CCTP for non-USDC. Each domain where
your token is active has its own independent TokenManager, and three roles
govern it: the owner (highest privilege, can change all roles), the operator
(sets rate limits and transfer caps), and the pauser (can pause and unpause the
token on this domain). You need to manage these roles when rotating keys,
delegating operator duties to a separate address, or responding to a security
incident.
Prerequisites
Before you begin, ensure that you’ve:- Registered a custom token using
registerCustomTokenordeployCrossChainToken, and noted thetokenId. See Configure a custom token - Noted the
CrossChainTokenServiceaddress for each domain where you want to change roles. See Contract addresses - Verified access to the wallet that currently holds the role you want to
change: the owner wallet for ownership, operator, or pauser changes; the
pauser wallet to call
pauseorunpause
Steps
1
Discover the TokenManager address
Every token has a separate Role changes apply only to the local
TokenManager per domain. Resolve its address from
the CrossChainTokenService before making any role change.TypeScript
TokenManager. Repeat the operation
independently on each domain where the token is deployed.2
Initiate ownership transfer
The current owner calls
transferOwnership to initiate. The TokenManager
enters a pending state—ownership has not changed yet. Ownership remains with the
current owner until the new owner accepts by calling acceptOwnership from
their address.TypeScript
3
Accept ownership
The pending owner calls
acceptOwnership. Ownership changes after this
transaction confirms.TypeScript
4
Replace the operator
Unlike ownership, operator replacement is a single-step operation. The current
owner calls The operator can call
transferOperatorship and the change takes effect immediately. No
additional acceptance step is required.TypeScript
setRateLimit, setMaxTransferAmount, and
setRateLimitWindow on the TokenManager. For details on configuring those
values, see
Configure rate limits and caps.5
Replace the pauser
The pauser role defaults to the operator address at deployment time. If you
never call
updatePauser, the operator is also the pauser. The current owner
can replace the pauser by calling updatePauser.TypeScript
6
Pause and unpause the token
The pauser can call
pause() to block all crosschain transfers of this token on
this domain, and unpause() to restore them.TypeScript
7
Verify the final state
After all transactions confirm, verify that
owner() returns the new owner,
operator() returns the new operator, pauser() returns the new pauser, and
paused() returns false after unpause().TypeScript