Skip to content

Instantly share code, notes, and snippets.

@janklimo
Created April 1, 2025 10:39
Show Gist options
  • Save janklimo/14f2c4ed60127963936b26b4c8dd128e to your computer and use it in GitHub Desktop.
Save janklimo/14f2c4ed60127963936b26b4c8dd128e to your computer and use it in GitHub Desktop.
HL lucky draw
import pandas as pd
import requests
import numpy as np
from typing import Dict, Tuple
class LuckyDrawSelector:
def __init__(
self,
):
self.comment_multiplier = 1.3
self.retweet_multiplier = 1.5
def get_staked_balance(self, wallet_address: str) -> float:
api_url = "https://api.hyperliquid.xyz/info"
payload = {"type": "delegations", "user": wallet_address}
try:
response = requests.post(
api_url, headers={"Content-Type": "application/json"}, json=payload
)
response.raise_for_status()
data = response.json()
# Find the delegation for PurrposefulNode
target_validator = "0xf8efb4cb844a8458114994203d7b0bfe2422a288"
for delegation in data:
if delegation["validator"] == target_validator:
return float(delegation["amount"])
return 0.0
except Exception as e:
print(f"Error fetching staked balance for {wallet_address}: {e}")
return 0.0
def calculate_score(
self, staked_amount: float, has_comment: bool, has_retweet: bool
) -> float:
# Quadratic voting principle: score is proportional to square root of staked amount
# This gives smaller stakers more representation
base_score = np.sqrt(staked_amount)
# Apply social action multipliers
if has_comment:
base_score *= self.comment_multiplier
if has_retweet:
base_score *= self.retweet_multiplier
return base_score
def load_participant_data(self, file_path: str) -> pd.DataFrame:
try:
df = pd.read_csv(file_path)
return df
except Exception as e:
raise Exception(f"Error loading participant data: {e}")
def process_participants(self, participants_df: pd.DataFrame) -> pd.DataFrame:
result_df = participants_df.copy()
result_df["staked_amount"] = result_df["address"].apply(self.get_staked_balance)
# Calculate scores using quadratic voting principle
result_df["score"] = result_df.apply(
lambda row: self.calculate_score(
row["staked_amount"], row["commented"], row["retweeted"]
),
axis=1,
)
# Calculate win chances (normalized weights)
valid_participants = result_df[result_df["score"] > 0]
weights = valid_participants["score"].values
normalized_weights = (
weights / pd.Series(weights).sum()
) # Normalize to probabilities
# Create a chance column, default to 0 for participants with 0 score
result_df["chance"] = 0.0
result_df.loc[valid_participants.index, "chance"] = normalized_weights
return result_df
def select_winner(self, scores_df: pd.DataFrame) -> str:
valid_participants = scores_df[scores_df["score"] > 0]
weights = valid_participants["score"].values
weights = weights / pd.Series(weights).sum() # Normalize to probabilities
# Select winner using weighted random choice
winner_index = np.random.choice(valid_participants.index, size=1, p=weights)[0]
winner_row = valid_participants.loc[winner_index]
return winner_row["address"]
def run_lucky_draw(self, file_path: str) -> Dict:
# Load and process data
participants_df = self.load_participant_data(file_path)
processed_df = self.process_participants(participants_df)
# Print statistics
total_participants = len(processed_df)
total_staked = processed_df["staked_amount"].sum()
print(f"Total participants: {total_participants}")
print(f"Total staked amount: {total_staked:.4f} HYPE")
print(f"Average stake: {total_staked / total_participants:.4f} HYPE")
# Print dataset with trimmed addresses
print("\nParticipant Data:")
display_df = processed_df.copy()
display_df["address"] = display_df["address"].apply(
lambda x: f"{x[:6]}...{x[-4:]}"
)
# Format chance as percentage with 2 decimal places
display_df["chance"] = (display_df["chance"] * 100).round(2).astype(str) + "%"
print(display_df.to_string(index=False))
# Select winner
winner_address = self.select_winner(processed_df)
winner_data = (
processed_df[processed_df["address"] == winner_address].iloc[0].to_dict()
)
return winner_data
def main():
selector = LuckyDrawSelector()
print(f"\n===== Running Lucky Draw =====")
winner = selector.run_lucky_draw("data.csv")
winner_address = winner["address"]
formatted_address = f"{winner_address[:6]}...{winner_address[-4:]}"
print(
f"\nThe winner is {formatted_address} ({winner['username']}). Congratulations 🎉"
)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment