arbret/backend/invite_utils.py

60 lines
1.5 KiB
Python

"""Utilities for invite code generation and validation."""
import random
from pathlib import Path
# Load BIP39 words from file
_WORDS_FILE = Path(__file__).parent / "words.txt"
with open(_WORDS_FILE) as f:
BIP39_WORDS = [line.strip() for line in f if line.strip()]
assert len(BIP39_WORDS) == 2048, f"Expected 2048 BIP39 words, got {len(BIP39_WORDS)}"
def generate_invite_identifier() -> str:
"""
Generate a unique invite identifier.
Format: word1-word2-NN where:
- word1, word2 are random BIP39 words
- NN is a two-digit number (00-99)
Returns lowercase identifier.
"""
word1 = random.choice(BIP39_WORDS)
word2 = random.choice(BIP39_WORDS)
number = random.randint(0, 99)
return f"{word1}-{word2}-{number:02d}"
def normalize_identifier(identifier: str) -> str:
"""
Normalize an invite identifier for comparison/lookup.
- Converts to lowercase
- Strips whitespace
"""
return identifier.strip().lower()
def is_valid_identifier_format(identifier: str) -> bool:
"""
Check if an identifier has valid format (word-word-NN).
Does NOT check if words are valid BIP39 words.
"""
parts = identifier.split("-")
if len(parts) != 3:
return False
word1, word2, number = parts
# Check words are non-empty
if not word1 or not word2:
return False
# Check number is two digits
if len(number) != 2 or not number.isdigit():
return False
return True