package tracking import ( "context" "fmt" "time" "github.com/jackc/pgx/v5/pgxpool" ) // Tracker tracks CCIP messages across chains type Tracker struct { db *pgxpool.Pool } // NewTracker creates a new CCIP tracker func NewTracker(db *pgxpool.Pool) *Tracker { return &Tracker{db: db} } // CCIPMessage represents a CCIP message type CCIPMessage struct { MessageID string SourceChainID int DestChainID int SourceTxHash string DestTxHash string Status string CreatedAt time.Time DeliveredAt *time.Time } // TrackMessage tracks a CCIP message func (t *Tracker) TrackMessage(ctx context.Context, msg *CCIPMessage) error { query := ` INSERT INTO ccip_messages ( message_id, source_chain_id, dest_chain_id, source_tx_hash, dest_tx_hash, status, created_at ) VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (message_id) DO UPDATE SET dest_tx_hash = $5, status = $6, delivered_at = CASE WHEN $6 = 'delivered' THEN NOW() ELSE delivered_at END ` _, err := t.db.Exec(ctx, query, msg.MessageID, msg.SourceChainID, msg.DestChainID, msg.SourceTxHash, msg.DestTxHash, msg.Status, msg.CreatedAt, ) return err } // GetMessage gets a CCIP message by ID func (t *Tracker) GetMessage(ctx context.Context, messageID string) (*CCIPMessage, error) { query := ` SELECT message_id, source_chain_id, dest_chain_id, source_tx_hash, dest_tx_hash, status, created_at, delivered_at FROM ccip_messages WHERE message_id = $1 ` var msg CCIPMessage err := t.db.QueryRow(ctx, query, messageID).Scan( &msg.MessageID, &msg.SourceChainID, &msg.DestChainID, &msg.SourceTxHash, &msg.DestTxHash, &msg.Status, &msg.CreatedAt, &msg.DeliveredAt, ) if err != nil { return nil, fmt.Errorf("failed to get message: %w", err) } return &msg, nil }