Tracking Module

Monitor cross-chain messages in real-time across Optimism Superchain networks. Track send and relay events with detailed timing and gas information.

Overview

The Tracking Module provides three main functions for monitoring cross-chain interoperability:

startTracking

Continuous monitoring loop that tracks messages at regular intervals

sendPing

Send a test message from origin to destination chain

waitForRelayedMessage

Wait for and track the relay of a specific message

startTracking

The main function for continuous cross-chain message monitoring. It runs in a loop, sending ping messages and tracking their relay status.

Function Signature

startTracking(chainsInfo, pksInfo, callback?, intervalMinutes?)
import { 
  startTracking, 
  TrackingResult, 
  TrackingCallback 
} from '@wakeuplabs/op-interop-alerts-sdk';
import { chainsInfoMock } from '@wakeuplabs/op-interop-alerts-sdk/config';

// Define your private keys
const pksInfo = {
  origin: process.env.ORIGIN_PRIVATE_KEY as `0x${string}`,
  destination: process.env.DESTINATION_PRIVATE_KEY as `0x${string}`,
};

// Define callback to handle tracking results
const trackingCallback: TrackingCallback = (result: TrackingResult) => {
  console.log(`[${result.timestamp.toISOString()}] Tracking result:`, result.success);
  
  if (result.success && result.data) {
    const { sentMessage, relayMessage } = result.data;
    
    // Calculate latency
    const latency = relayMessage.localTimestamp.getTime() - 
                   sentMessage.localTimestamp.getTime();
    
    console.log(`✅ Message relayed successfully in ${latency}ms`);
    console.log(`📊 Gas used - Send: ${sentMessage.gasUsed}, Relay: ${relayMessage.gasUsed}`);
    
  } else if (result.error) {
    console.error(`❌ Tracking failed: ${result.error.error.message}`);
  }
};

// Start continuous tracking (checks every 10 minutes)
async function main() {
  try {
    await startTracking(
      chainsInfoMock,
      pksInfo, 
      trackingCallback,
      10 // Check every 10 minutes
    );
  } catch (error) {
    console.error('Failed to start tracking:', error);
  }
}

main();

Parameters

ParameterTypeDescription
chainsInfoChainsInfoConfiguration for origin and destination chains
pksInfoPKsInfoPrivate keys for both chains
callbackTrackingCallback?Optional callback function for tracking results
intervalMinutesnumber?Interval between checks in minutes (default: 10)

sendPing

Send a test message from the origin chain to the destination chain. This function returns detailed information about the sent message.

import { 
  sendPing, 
  SendPingResult 
} from '@wakeuplabs/op-interop-alerts-sdk';
import { chainsInfoMock } from '@wakeuplabs/op-interop-alerts-sdk/config';

const pksInfo = {
  origin: process.env.ORIGIN_PRIVATE_KEY as `0x${string}`,
  destination: process.env.DESTINATION_PRIVATE_KEY as `0x${string}`,
};

async function testSendPing() {
  try {
    const result: SendPingResult = await sendPing(chainsInfoMock, pksInfo);
    
    if (result.status === 'SUCCESS') {
      console.log('✅ Ping sent successfully!');
      console.log('Transaction Hash:', result.data.transactionHash);
      console.log('Gas Used:', result.data.eventData.gasUsed.toString());
      console.log('Message Sender:', result.data.sentMessageSender);
      console.log('Message Payload:', result.data.sentMessagePayload);
      
      // Access the event data
      const eventData = result.data.eventData;
      console.log('Event Args:', {
        destination: eventData.event.args.destination?.toString(),
        target: eventData.event.args.target,
        messageNonce: eventData.event.args.messageNonce?.toString(),
        sender: eventData.event.args.sender
      });
      
    } else {
      console.error('❌ Failed to send ping:', result.error.message);
    }
  } catch (error) {
    console.error('Error sending ping:', error);
  }
}

testSendPing();

waitForRelayedMessage

Wait for and track the relay of a specific message on the destination chain. This function monitors for the RelayedMessage event that corresponds to a previously sent message.

import { 
  sendPing, 
  waitForRelayedMessage,
  WaitForRelayedMessageResult 
} from '@wakeuplabs/op-interop-alerts-sdk';
import { chainsInfoMock } from '@wakeuplabs/op-interop-alerts-sdk/config';

const pksInfo = {
  origin: process.env.ORIGIN_PRIVATE_KEY as `0x${string}`,
  destination: process.env.DESTINATION_PRIVATE_KEY as `0x${string}`,
};

async function trackMessageRelay() {
  try {
    // First, send a ping message
    const sendResult = await sendPing(chainsInfoMock, pksInfo);
    
    if (sendResult.status !== 'SUCCESS') {
      console.error('Failed to send ping:', sendResult.error.message);
      return;
    }
    
    console.log('✅ Ping sent, waiting for relay...');
    
    // Wait for the message to be relayed
    const relayResult: WaitForRelayedMessageResult = await waitForRelayedMessage(
      chainsInfoMock,
      sendResult.data.sentMessageSender,
      sendResult.data.sentMessagePayload
    );
    
    if (relayResult.status === 'SUCCESS') {
      console.log('✅ Message relayed successfully!');
      
      const relayData = relayResult.data;
      console.log('Relay Transaction Hash:', relayData.transactionHash);
      console.log('Relay Gas Used:', relayData.eventData.gasUsed.toString());
      
      // Calculate total latency
      const sendTime = sendResult.data.eventData.localTimestamp;
      const relayTime = relayData.eventData.localTimestamp;
      const latency = relayTime.getTime() - sendTime.getTime();
      
      console.log(`⏱️  Total latency: ${latency}ms`);
      
      // Access relay event data
      const eventData = relayData.eventData;
      console.log('Relay Event Args:', {
        source: eventData.event.args.source?.toString(),
        messageNonce: eventData.event.args.messageNonce?.toString(),
        messageHash: eventData.event.args.messageHash,
        returnDataHash: eventData.event.args.returnDataHash
      });
      
    } else {
      console.error('❌ Failed to wait for relay:', relayResult.error.message);
    }
    
  } catch (error) {
    console.error('Error tracking message relay:', error);
  }
}

trackMessageRelay();

Best Practices

Handle Errors Gracefully

Always check the status of results and handle both success and failure cases. Network issues and chain congestion can cause temporary failures.

Use Appropriate Intervals

Choose tracking intervals based on your needs. Shorter intervals provide more data but consume more resources. For production monitoring, 5-10 minutes is usually sufficient.

Store Tracking Results

Keep a history of tracking results to generate meaningful metrics and detect patterns. This data is essential for the Metrics and Alerts modules.

Avoid Very Short Intervals

Don't set intervals shorter than 1 minute as this can overwhelm the networks and may be considered spam by RPC providers.

Next Steps

Now that you understand message tracking, learn how to generate metrics from your tracking data: