Summary
The MessageTransmitterV2 contract provides is_nonce_used(nonce: BytesN<32>) -> bool to check if a specific nonce has been used, but there is no mechanism for clients to discover or enumerate nonces.
Problem
When building relay/indexer services on top of Stellar CCTP, operators need to track which cross-chain messages have been processed. Currently, the only ways to determine nonce usage are:
-
Call is_nonce_used() for a known nonce - This requires already knowing the nonce value from an off-chain source (e.g., indexing MessageSent events on the source chain).
-
Attempt receive_message() and catch NonceAlreadyUsed (error 6908) - This is expensive and unreliable as a discovery mechanism.
-
Index MessageReceived events off-chain - This works but requires maintaining a separate off-chain indexer, adding operational complexity for relay operators.
Suggested Enhancement
Consider adding one or more of the following query functions to MessageTransmitterV2:
Option A: Nonce count query
/// Returns the total number of nonces that have been used.
pub fn get_used_nonce_count(e: &Env) -> u64
Option B: Batch nonce check
/// Checks multiple nonces at once, returning a Vec of booleans.
pub fn are_nonces_used(e: &Env, nonces: Vec<BytesN<32>>) -> Vec<bool>
Option B would be particularly useful for relay services that need to check a batch of pending messages before deciding which ones to relay, reducing the number of contract calls from N to 1.
Use Case
- Relay services: Need to efficiently determine which messages from a source chain have already been relayed to Stellar.
- Cross-chain bridges UI: Want to show users the status of their pending transfers without maintaining a separate indexer.
- Monitoring dashboards: Need to track CCTP message throughput and identify stuck messages.
Context
This is consistent with patterns in other CCTP implementations. For example, on EVM CCTP, the usedNonces mapping is publicly accessible, and sequential nonces make enumeration trivial. On Stellar, the BytesN<32> nonce format makes enumeration impossible without additional contract support or off-chain indexing.
Impact
- No breaking changes - purely additive query functions
- Low risk - read-only operations with no state mutation
- High developer value - significantly improves the developer experience for building relay infrastructure
Summary
The
MessageTransmitterV2contract providesis_nonce_used(nonce: BytesN<32>) -> boolto check if a specific nonce has been used, but there is no mechanism for clients to discover or enumerate nonces.Problem
When building relay/indexer services on top of Stellar CCTP, operators need to track which cross-chain messages have been processed. Currently, the only ways to determine nonce usage are:
Call
is_nonce_used()for a known nonce - This requires already knowing the nonce value from an off-chain source (e.g., indexingMessageSentevents on the source chain).Attempt
receive_message()and catchNonceAlreadyUsed(error 6908) - This is expensive and unreliable as a discovery mechanism.Index
MessageReceivedevents off-chain - This works but requires maintaining a separate off-chain indexer, adding operational complexity for relay operators.Suggested Enhancement
Consider adding one or more of the following query functions to
MessageTransmitterV2:Option A: Nonce count query
Option B: Batch nonce check
Option B would be particularly useful for relay services that need to check a batch of pending messages before deciding which ones to relay, reducing the number of contract calls from N to 1.
Use Case
Context
This is consistent with patterns in other CCTP implementations. For example, on EVM CCTP, the
usedNoncesmapping is publicly accessible, and sequential nonces make enumeration trivial. On Stellar, theBytesN<32>nonce format makes enumeration impossible without additional contract support or off-chain indexing.Impact