For the complete documentation index, see llms.txt. This page is also available as Markdown.

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

Function
Access
Reverts with

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.

Function of the token
Access
Message

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:

#
Check
Reverts with

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

Function
Access
Behavior

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

Element
Definition

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

Function
Returns

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

Event
Emitted when

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