Messaging
The token is the only author and the only recipient of an asset's cross-chain messages on the reference chain. This page lists the three pieces behind that: TREXMessaging, which the token inherits, the TrustedGatewayRegistry of the network, and the library MessageTypesLib that defines the wire format. The concept is in Messaging: ERC-7786 gateways, routes and peers.
At a glance
Source
contracts/interop/TREXMessaging.sol, contracts/interop/TrustedGatewayRegistry.sol, contracts/libraries/MessageTypesLib.sol, contracts/libraries/WalletKeyLib.sol
Interfaces
ITREXMessaging, ITrustedGatewayRegistry, ISettlementHandler, OpenZeppelin's IERC7786GatewaySource and IERC7786Recipient
Deployed as
TREXMessaging is part of each Token. The TrustedGatewayRegistry is one contract per network, not upgradeable
Roles
IDENTITY_MANAGER of the asset for routes and peers. The platform role INTEROP_MANAGER for the list of trusted gateways
Routes and peers, on the token
setRoute(chainType, chainReference, gateway)
IDENTITY_MANAGER
GatewayNotTrusted unless the gateway is trusted or zero, InvalidChainReference for an empty reference or, on an EVM chain, one with a leading zero byte. A zero gateway closes the chain. Emits ChainRegistered the first time, and RouteSet
setPeer(chainKey, peer)
IDENTITY_MANAGER
ChainNotRegistered, InvalidPeer for an address with no account part or with trailing bytes, PeerChainMismatch. Emits PeerSet
routeFor(chainKey)
Anyone, read
The gateway of a chain, or zero
peerFor(chainKey)
Anyone, read
The peer as an ERC-7930 address. On an EVM chain with no registered peer, the token's own address on that chain
chainOf(chainKey)
Anyone, read
The chainType and chainReference behind a key
isChainOpen(chainKey)
Anyone, read
True when the chain has a route, the route is trusted at that moment, and a peer is known
pinnedRouteFor(validationId, chainKey)
Anyone, read
The gateway a validation went out through toward a chain
messageReceived(gateway, receiveId)
Anyone, read
Whether a gateway already delivered a receiveId
trustedGatewayRegistry()
Anyone, read
The registry the token reads
Guide: 33 Open an asset on a satellite.
Sending
Every outbound message goes through one call: sendMessage(recipient, payload, attributes) on the gateway of the chain, with the peer as recipient, an empty list of attributes and no value.
dispatchComplianceValidation(chainKey, validationId, body)
The bound compliance
COMPLIANCE_VALIDATION. Records the gateway used (ValidationRoutePinned). Reverts with SenderNotCompliance, ChainNotOpen, ValidationAlreadyRouted
dispatchMintInstruction(chainKey, body)
AGENT
MINT_INSTRUCTION. Reverts with ChainNotOpen
dispatchRecallInstruction(chainKey, body)
AGENT
RECALL_INSTRUCTION. Reverts with ChainNotOpen
Each emits ProtocolMessageSent with the sendId the gateway returned.
Receiving
A gateway delivers with receiveMessage(receiveId, sender, payload). The token checks, in this order:
1
The caller is trusted in the TrustedGatewayRegistry at that moment
ERC7786RecipientUnauthorizedGateway
2
sender parses as an ERC-7930 version 1 address and names a chain
InteroperableAddressParsingError, InteroperableAddressEmptyReferenceAndAddress
3
sender is, byte for byte, the peer of that chain
SenderNotPeer
4
The payload decodes to a defined type, with version 1
UnsupportedMessageVersion
5
This gateway has not delivered this receiveId
MessageAlreadyReceived
6
Settlement: the caller is the gateway the validation went out through, or the route of the chain when the token never sent that validation there
GatewayNotPinned, GatewayNotRouted
7
Settlement: the token is not paused, and the compliance accepts the report
EnforcedPause, and the errors of Transfer validation
8
Burn proof: the caller is the route of the chain, and the proof names an address to credit
GatewayNotRouted, ZeroAddress
9
Any other type
MessageTypeNotInbound
On success the token emits ProtocolMessageReceived. When the compliance reports a replayed or unknown settlement, the token applies nothing and pauses itself. What a gateway must guarantee is in Build an ERC-7786 gateway adapter.
TrustedGatewayRegistry
setTrustedGateway(gateway, trusted)
INTEROP_MANAGER
Adds a gateway to the list of the network, or removes it. Reverts with ZeroAddress. Emits TrustedGatewaySet(address indexed gateway, bool trusted)
isTrusted(gateway)
Anyone, read
Tokens call it on every send and every delivery
Removing a gateway severs every route through it at once, for every asset, validations in flight included.
MessageTypesLib
Message
The enum of message types: COMPLIANCE_VALIDATION 0, MINT_INSTRUCTION 1, RECALL_INSTRUCTION 2, SETTLEMENT_NOTIFICATION 3, BURN_PROOF 4
VERSION
1
encode(messageType, body), decode(payload)
The envelope: abi.encode(messageType, VERSION, body). decode reverts with UnsupportedMessageVersion
ComplianceValidation
(uint256 validationId, bytes from, bytes to, bytes spender, uint256 amountMin, uint256 amountMax, address token, uint64 expiry, uint64 reconciliationWindow)
SettlementNotification
(uint256 validationId, bytes from, bytes to, uint256 amount)
BurnProof
(bytes burnedWallet, uint256 amount, address nativeWallet)
encodeValidation, decodeValidation, encodeSettlement, decodeSettlement, encodeBurnProof, decodeBurnProof
The three encoders return the full payload, envelope included. The three decoders take a body and return the struct
hashValidation(validation)
The ERC-712 struct hash of a validation, stored by the compliance
chainKey(chainType, chainReference)
The keccak256 of the ERC-7930 address of the chain, with an empty account
The format is described field by field in Implement T-REX Lite on a new chain.
WalletKeyLib
parse(envelope)
The parts of an ERC-7930 address. Reverts with NonCanonicalInteroperableAddress for trailing bytes or, on an EVM chain, a chain reference with a leading zero byte
canonicalKey(envelope)
The keccak256 of a canonical address
satelliteKey(envelope)
The same, for a wallet that must be on another chain: reverts with NotASatelliteWallet for a wallet of the reference chain
walletId(envelope), walletId(wallet)
The bytes32 key the ledger uses: an address of the reference chain padded on the left, the keccak256 for a satellite wallet
isReferenceChain(envelope)
Whether the address is on the reference chain, and the address when it is
Events
ChainRegistered(bytes32 indexed chainKey, bytes2 chainType, bytes chainReference)
First route for a chain
RouteSet(bytes32 indexed chainKey, address indexed gateway), PeerSet(bytes32 indexed chainKey, bytes peer)
The gateway, the peer, of a chain
TrustedGatewayRegistrySet(address trustedGatewayRegistry)
Once, at deployment of the token
ValidationRoutePinned(uint256 indexed validationId, bytes32 indexed chainKey, address gateway)
First dispatch of a validation to a chain
ProtocolMessageSent(MessageTypesLib.Message indexed messageType, bytes32 indexed chainKey, bytes32 sendId)
A message leaves
ProtocolMessageReceived(MessageTypesLib.Message indexed messageType, bytes32 indexed chainKey, bytes32 receiveId)
A message was processed
BurnProofReceived(bytes32 indexed originChainKey, bytes burnedWallet, address indexed nativeWallet, uint256 amount)
A burn proof arrives
TrustedGatewaySet(address indexed gateway, bool trusted)
On the registry: a gateway is trusted, or no longer
Last updated