stones/scripts/moloch_dao/resolve_public_haus_ens.py

147 lines
5.1 KiB
Python

#!/usr/bin/env python3
"""
Resolve ENS Names for Public Haus Members
This script resolves ENS names for Public Haus members imported from the DAOhaus API on Optimism mainnet.
It updates the contacts with ENS names and profile information, and links them to the data source.
"""
import os
import sys
import logging
from typing import Dict, Any, List, Optional
from web3 import Web3
from dotenv import load_dotenv
# Add parent directory to path to import utils
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils.db_connector import DatabaseConnector
from utils.ens_resolver import ENSResolver
from utils.logger import setup_logger
# Load environment variables
load_dotenv()
# Setup logging
logger = setup_logger("public_haus_ens_resolver")
class PublicHausENSResolver:
"""Resolver for ENS names of Public Haus members"""
def __init__(self):
"""Initialize the resolver"""
# Initialize database
self.db = DatabaseConnector()
# Initialize Web3 and ENS resolver
alchemy_api_key = os.getenv("ALCHEMY_API_KEY")
if not alchemy_api_key:
raise ValueError("ALCHEMY_API_KEY not found in environment variables")
self.web3 = Web3(Web3.HTTPProvider(f"https://eth-mainnet.g.alchemy.com/v2/{alchemy_api_key}"))
self.ens_resolver = ENSResolver(self.web3)
# Get data source ID
self.data_source_id = self.get_data_source_id()
def get_data_source_id(self) -> str:
"""Get the ID of the Public Haus DAO API data source"""
query = 'SELECT id FROM "DataSource" WHERE name = %(name)s'
result = self.db.execute_query(query, {"name": "Public Haus DAO Tokens"})
if not result:
raise ValueError("Public Haus DAO Tokens data source not found")
return result[0]["id"]
def get_public_haus_members(self) -> List[Dict[str, Any]]:
"""Get all Public Haus members from the database"""
query = """
SELECT c.id, c."ethereumAddress", c."ensName"
FROM "Contact" c
JOIN "DaoMembership" dm ON c.id = dm."contactId"
WHERE dm."daoName" = 'Public Haus'
"""
return self.db.execute_query(query)
def resolve_ens_for_member(self, contact_id: str, ethereum_address: str, current_ens: Optional[str] = None) -> bool:
"""
Resolve ENS name for a member and update their profile.
Args:
contact_id: ID of the contact
ethereum_address: Ethereum address of the member
current_ens: Current ENS name of the member, if any
Returns:
True if ENS was resolved or already exists, False otherwise
"""
# Skip if already has ENS
if current_ens:
logger.info(f"Contact {contact_id} already has ENS: {current_ens}")
# Still update profile from ENS if needed
self.ens_resolver.update_contact_from_ens(contact_id, current_ens)
# Link to data source
self.db.link_contact_to_data_source(contact_id, self.data_source_id)
return True
# Resolve ENS name
ens_name = self.ens_resolver.get_ens_name(ethereum_address)
if not ens_name:
logger.info(f"No ENS name found for {ethereum_address}")
# Still link to data source
self.db.link_contact_to_data_source(contact_id, self.data_source_id)
return False
# Update contact with ENS name
self.db.update_contact(contact_id, {"ensName": ens_name})
logger.info(f"Updated contact {contact_id} with ENS name: {ens_name}")
# Update profile from ENS
self.ens_resolver.update_contact_from_ens(contact_id, ens_name)
# Link to data source
self.db.link_contact_to_data_source(contact_id, self.data_source_id)
return True
def run(self):
"""Run the resolver"""
logger.info("Starting ENS resolution for Public Haus members")
# Get all Public Haus members
members = self.get_public_haus_members()
logger.info(f"Found {len(members)} Public Haus members")
# Resolve ENS for each member
resolved_count = 0
for member in members:
if self.resolve_ens_for_member(
member["id"],
member["ethereumAddress"],
member.get("ensName")
):
resolved_count += 1
logger.info(f"Resolved ENS for {resolved_count} out of {len(members)} members")
return resolved_count
def main():
"""Main function"""
try:
resolver = PublicHausENSResolver()
resolved_count = resolver.run()
logger.info(f"ENS resolution completed successfully. Resolved {resolved_count} members.")
return 0
except Exception as e:
logger.exception(f"Error resolving ENS names: {e}")
return 1
if __name__ == "__main__":
sys.exit(main())