package labels import ( "context" "fmt" "github.com/jackc/pgx/v5/pgxpool" ) // LabelService handles address labeling type LabelService struct { db *pgxpool.Pool } // NewLabelService creates a new label service func NewLabelService(db *pgxpool.Pool) *LabelService { return &LabelService{db: db} } // AddLabel adds a label to an address func (l *LabelService) AddLabel(ctx context.Context, chainID int, address, label, labelType string, userID *string) error { query := ` INSERT INTO address_labels (chain_id, address, label, label_type, user_id) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (chain_id, address, label_type, user_id) DO UPDATE SET label = $3, updated_at = NOW() ` _, err := l.db.Exec(ctx, query, chainID, address, label, labelType, userID) return err } // GetLabels gets labels for an address func (l *LabelService) GetLabels(ctx context.Context, chainID int, address string) ([]Label, error) { query := ` SELECT label, label_type, user_id, source, created_at FROM address_labels WHERE chain_id = $1 AND address = $2 ORDER BY created_at DESC ` rows, err := l.db.Query(ctx, query, chainID, address) if err != nil { return nil, fmt.Errorf("failed to query labels: %w", err) } defer rows.Close() var labels []Label for rows.Next() { var label Label var userID *string if err := rows.Scan(&label.Label, &label.LabelType, &userID, &label.Source, &label.CreatedAt); err != nil { continue } if userID != nil { label.UserID = *userID } labels = append(labels, label) } return labels, nil } // Label represents an address label type Label struct { Label string LabelType string UserID string Source string CreatedAt string }