Shared library for uSipipo ecosystem
Project description
uSipipo Commons
Shared library for the uSipipo VPN ecosystem
Overview
uSipipo Commons is the shared library for the uSipipo VPN ecosystem, providing domain entities, enums, constants, and utilities used across all uSipipo services.
What It Provides
- Domain Entities: Core business entities (User, VpnKey, Payment, Subscription, etc.)
- Enums: Type-safe enumerations for statuses, methods, and types
- Constants: Shared constants for plans, limits, and error codes
- Utilities: Validation and formatting helper functions
What Projects Use It
usipipo-backend- FastAPI backend APIusipipo-telegram-bot- Telegram botusipipo-miniapp-web- Telegram Mini Appusipipo-landing- Marketing site
Installation
From PyPI (Recommended)
pip install usipipo-commons
From GitHub (Development)
pip install git+https://github.com/uSipipo-Team/usipipo-commons.git
Local Development
# Clone the repository
git clone https://github.com/uSipipo-Team/usipipo-commons.git
cd usipipo-commons
# Install with uv (recommended)
uv sync --dev
# Or with pip
pip install -e .
Quick Start
from usipipo_commons.domain.entities import User, VpnKey, Payment, SubscriptionPlan
from usipipo_commons.domain.enums import KeyType, KeyStatus, PaymentStatus, PlanType
from usipipo_commons.schemas import CreateVpnKeyRequest, PaymentResponse
from usipipo_commons.constants import FREE_GB, REFERRAL_BONUS_GB, PRICE_PER_GB
from usipipo_commons.utils import validate_telegram_id, format_bytes, format_datetime
from datetime import datetime, timezone
from uuid import uuid4
# Create a User entity
user = User(
id=uuid4(),
telegram_id=123456789,
username="johndoe",
first_name="John",
last_name="Doe",
is_admin=False,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc),
balance_gb=5.0,
total_purchased_gb=0.0,
referral_code="JOHN123",
referred_by=None,
)
# Create a VPN Key entity
vpn_key = VpnKey(
user_id=user.id,
key_type=KeyType.OUTLINE,
status=KeyStatus.ACTIVE,
name="My VPN Key",
key_data="ss://...",
data_limit_bytes=5 * 1024**3, # 5 GB
)
# Use constants
print(f"Free GB: {FREE_GB}") # 5.0
print(f"Referral Bonus: {REFERRAL_BONUS_GB} GB") # 5.0
print(f"Price per GB: ${PRICE_PER_GB}") # $0.50
# Use utilities
assert validate_telegram_id(123456789) == True
print(format_bytes(5.5)) # "5.50 GB"
print(format_datetime(datetime.now(timezone.utc))) # "2026-03-22 12:00:00 UTC"
# Convert entity to dict for serialization
user_dict = user.to_dict()
vpn_key_dict = vpn_key.to_dict()
Domain Entities
Core Entities
User
Represents a user in the uSipipo ecosystem.
Properties:
id: UUID- Unique user identifiertelegram_id: int- Telegram user IDusername: Optional[str]- Telegram usernamefirst_name: Optional[str]- User's first namelast_name: Optional[str]- User's last nameis_admin: bool- Whether user has admin privilegescreated_at: datetime- Account creation timestampupdated_at: datetime- Last update timestampbalance_gb: float- Available data balance in GBtotal_purchased_gb: float- Total GB purchased historicallyreferral_code: str- User's unique referral codereferred_by: Optional[UUID]- ID of user who referred this userreferral_credits: int- Credits earned from referralspurchase_count: int- Number of purchases madeloyalty_bonus_percent: int- Loyalty bonus percentagewelcome_bonus_used: bool- Whether welcome bonus was usedreferred_users_with_purchase: int- Number of referred users who made purchases
Example:
from usipipo_commons.domain.entities import User
from datetime import datetime, timezone
from uuid import uuid4
user = User(
id=uuid4(),
telegram_id=123456789,
username="johndoe",
first_name="John",
last_name="Doe",
is_admin=False,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc),
balance_gb=5.0,
total_purchased_gb=10.0,
referral_code="JOHN123",
referred_by=None,
referral_credits=5,
purchase_count=2,
)
VpnKey
Represents a VPN access credential.
Properties:
id: UUID- Unique key identifieruser_id: UUID- Owner's user IDkey_type: KeyType- VPN type (OUTLINE or WIREGUARD)status: KeyStatus- Key status (ACTIVE, EXPIRED, REVOKED, PENDING)name: str- User-friendly key namekey_data: str- Connection string (ss://... or WireGuard config)external_id: str- Server-assigned ID (Outline/WireGuard)created_at: datetime- Creation timestampused_bytes: int- Data consumed in byteslast_seen_at: Optional[datetime]- Last client activitydata_limit_bytes: int- Data limit in bytesbilling_reset_at: datetime- Billing cycle reset dateexpires_at: Optional[datetime]- Key expiration date
Computed Properties:
is_active: bool- True if status is ACTIVEused_mb: float- Usage in MBused_gb: float- Usage in GBdata_limit_gb: float- Limit in GBremaining_bytes: int- Remaining data in bytesis_over_limit: bool- True if over data limit
Methods:
needs_reset() -> bool- Check if 30 days passed since last resetreset_billing_cycle()- Reset billing cycleadd_usage(bytes_used: int)- Add data usageto_dict() -> dict- Convert to dictionary
Example:
from usipipo_commons.domain.entities import VpnKey
from usipipo_commons.domain.enums import KeyType, KeyStatus
from uuid import uuid4
vpn_key = VpnKey(
user_id=uuid4(),
key_type=KeyType.OUTLINE,
status=KeyStatus.ACTIVE,
name="Home VPN",
key_data="ss://YWVzLTI1Ni1nY206...",
data_limit_bytes=5 * 1024**3, # 5 GB
)
print(f"Used: {vpn_key.used_gb:.2f} GB")
print(f"Remaining: {vpn_key.remaining_bytes / 1024**3:.2f} GB")
print(f"Active: {vpn_key.is_active}")
# Add usage
vpn_key.add_usage(1024 * 1024 * 500) # 500 MB
Balance
Represents user balance in stars (Telegram payment units).
Properties:
user_id: UUID- User identifierstars: int- Balance in stars
Methods:
add(amount: int) -> Balance- Add amount and return new Balancesubtract(amount: int) -> Balance- Subtract amount and return new Balancehas_sufficient(amount: int) -> bool- Check if balance is sufficient
Example:
from usipipo_commons.domain.entities import Balance
import uuid
balance = Balance(user_id=uuid.uuid4(), stars=1000)
# Add stars
new_balance = balance.add(500)
print(new_balance.stars) # 1500
# Check sufficient
print(balance.has_sufficient(800)) # True
# Subtract
remaining = balance.subtract(300)
print(remaining.stars) # 700
Payment Entities
Payment
Represents a payment transaction.
Properties:
id: UUID- Unique payment identifieruser_id: UUID- User who made the paymentamount_usd: float- Payment amount in USDgb_purchased: float- GB purchased in this paymentmethod: PaymentMethod- Payment method usedstatus: PaymentStatus- Payment statuscrypto_address: Optional[str]- Crypto wallet address (if crypto payment)crypto_network: Optional[str]- Crypto network (e.g., BSC, TRC20)telegram_star_invoice_id: Optional[str]- Telegram Stars invoice IDcreated_at: datetime- Payment creation timestampexpires_at: Optional[datetime]- Payment expiration timestamppaid_at: Optional[datetime]- Payment completion timestamptransaction_hash: Optional[str]- Blockchain transaction hash
Example:
from usipipo_commons.domain.entities import Payment
from usipipo_commons.domain.enums import PaymentMethod, PaymentStatus
from datetime import datetime, timezone
from uuid import uuid4
payment = Payment(
id=uuid4(),
user_id=uuid4(),
amount_usd=5.00,
gb_purchased=10.0,
method=PaymentMethod.CRYPTO_USDT,
status=PaymentStatus.PENDING,
crypto_address="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
crypto_network="BSC",
created_at=datetime.now(timezone.utc),
)
CryptoOrder
Represents a cryptocurrency order.
Properties:
id: UUID- Unique order identifieruser_id: UUID- User who created the orderpackage_type: str- Package type purchasedamount_usdt: float- Amount in USDTwallet_address: str- Destination wallet addresstron_dealer_order_id: Optional[str]- TronDealer order IDstatus: CryptoOrderStatus- Order statuscreated_at: datetime- Order creation timestampexpires_at: datetime- Order expiration timestamptx_hash: Optional[str]- Transaction hashconfirmed_at: Optional[datetime]- Confirmation timestamp
Methods:
create(user_id, package_type, amount_usdt, wallet_address) -> CryptoOrder- Factory methodto_dict() -> dict- Convert to dictionary
Example:
from usipipo_commons.domain.entities import CryptoOrder
from uuid import uuid4
order = CryptoOrder.create(
user_id=uuid4(),
package_type="premium",
amount_usdt=10.0,
wallet_address="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
)
CryptoTransaction
Represents a detected blockchain transaction.
Properties:
id: UUID- Unique transaction identifieruser_id: Optional[UUID]- Associated user IDwallet_address: str- Wallet address involvedamount: float- Transaction amounttoken_symbol: str- Token symbol (default: USDT)tx_hash: str- Transaction hashstatus: CryptoTransactionStatus- Transaction statusconfirmations: int- Number of confirmationsconfirmed_at: Optional[datetime]- Confirmation timestampcreated_at: datetime- Detection timestampraw_payload: dict- Raw transaction data
Properties:
is_confirmed: bool- True if status is CONFIRMEDis_pending: bool- True if status is PENDING
Methods:
confirm()- Mark as confirmedfail()- Mark as failedcreate(wallet_address, amount, tx_hash, token_symbol, raw_payload) -> CryptoTransaction- Factory method
Example:
from usipipo_commons.domain.entities import CryptoTransaction
tx = CryptoTransaction.create(
wallet_address="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
amount=10.0,
tx_hash="0xabc123...",
token_symbol="USDT",
)
tx.confirm()
print(tx.is_confirmed) # True
WebhookToken
Token for validating webhooks.
Properties:
id: UUID- Unique token identifiertoken_hash: str- Hashed token valuepurpose: str- Token purpose (default: "tron_dealer")created_at: datetime- Creation timestampexpires_at: datetime- Expiration timestampused_at: Optional[datetime]- Usage timestampextra_data: dict- Additional data
Properties:
is_expired: bool- True if token is expiredis_used: bool- True if token was used
Methods:
mark_used()- Mark token as usedcreate(token_hash, purpose) -> WebhookToken- Factory method
Example:
from usipipo_commons.domain.entities import WebhookToken
token = WebhookToken.create(
token_hash="abc123...",
purpose="tron_dealer",
)
if not token.is_expired and not token.is_used:
token.mark_used()
Subscription Entities
SubscriptionPlan
Represents an active user subscription plan.
Properties:
user_id: UUID- User IDplan_type: PlanType- Plan type (ONE_MONTH, THREE_MONTHS, SIX_MONTHS)stars_paid: int- Stars paid for subscriptionpayment_id: str- Associated payment IDstarts_at: datetime- Subscription start dateexpires_at: datetime- Subscription expiration dateid: UUID- Unique subscription identifieris_active: bool- Whether subscription is activecreated_at: datetime- Creation timestampupdated_at: datetime- Last update timestamp
Properties:
is_expired: bool- True if subscription is expireddays_remaining: int- Days remaining until expirationis_expiring_soon: bool- True if expires within 7 days
Example:
from usipipo_commons.domain.entities import SubscriptionPlan
from usipipo_commons.domain.enums import PlanType
from datetime import datetime, timezone, timedelta
from uuid import uuid4
now = datetime.now(timezone.utc)
plan = SubscriptionPlan(
user_id=uuid4(),
plan_type=PlanType.ONE_MONTH,
stars_paid=1200,
payment_id="pay_123",
starts_at=now,
expires_at=now + timedelta(days=30),
)
print(f"Days remaining: {plan.days_remaining}")
print(f"Expiring soon: {plan.is_expiring_soon}")
SubscriptionTransaction
Represents a subscription transaction for tracking and idempotency.
Properties:
transaction_id: str- Unique transaction identifieruser_id: UUID- User IDplan_type: str- Plan typeamount_stars: int- Amount in starspayload: str- Transaction payloadstatus: SubscriptionTransactionStatus- Transaction statuscreated_at: Optional[datetime]- Creation timestampexpires_at: Optional[datetime]- Expiration timestamp (30 minutes)completed_at: Optional[datetime]- Completion timestampid: Optional[UUID]- Internal ID
Properties:
is_pending: bool- True if status is PENDINGis_completed: bool- True if status is COMPLETEDis_expired: bool- True if transaction is expired
Methods:
mark_completed()- Mark as completedmark_failed()- Mark as failedmark_expired()- Mark as expired
Example:
from usipipo_commons.domain.entities import SubscriptionTransaction
from uuid import uuid4
tx = SubscriptionTransaction(
transaction_id="tx_123",
user_id=uuid4(),
plan_type="one_month",
amount_stars=1200,
payload="{}",
)
tx.mark_completed()
print(tx.is_completed) # True
Consumption Billing Entities
ConsumptionBilling
Represents a billing cycle for consumption-based billing.
Properties:
user_id: int- User IDstarted_at: datetime- Cycle start datestatus: BillingStatus- Cycle status (ACTIVE, CLOSED, PAID, CANCELLED)id: Optional[UUID]- Unique cycle identifierended_at: Optional[datetime]- Cycle end datemb_consumed: Decimal- MB consumed in cycletotal_cost_usd: Decimal- Total cost in USDprice_per_mb_usd: Decimal- Price per MB (default: $0.000244140625)created_at: datetime- Creation timestamp
Properties:
is_active: bool- True if status is ACTIVEis_closed: bool- True if status is CLOSEDis_paid: bool- True if status is PAIDgb_consumed: Decimal- GB consumed (formatted)
Methods:
add_consumption(mb_used: Decimal)- Add consumption to cycleclose_cycle()- Close the billing cyclemark_as_paid()- Mark cycle as paidget_formatted_cost() -> str- Get formatted cost stringget_formatted_consumption() -> str- Get formatted consumption string
Example:
from usipipo_commons.domain.entities import ConsumptionBilling
from usipipo_commons.domain.enums import BillingStatus
from datetime import datetime, timezone
from decimal import Decimal
cycle = ConsumptionBilling(
user_id=123456789,
started_at=datetime.now(timezone.utc),
)
# Add consumption
cycle.add_consumption(Decimal("512.5")) # 512.5 MB
print(cycle.get_formatted_consumption()) # "512.50 MB"
print(cycle.get_formatted_cost()) # "$0.13 USD"
# Close cycle
cycle.close_cycle()
print(cycle.is_closed) # True
# Mark as paid
cycle.mark_as_paid()
print(cycle.is_paid) # True
ConsumptionInvoice
Represents an invoice for consumption payment.
Properties:
billing_id: UUID- Associated billing cycle IDuser_id: int- User IDamount_usd: Decimal- Invoice amount in USDwallet_address: str- Wallet address for paymentpayment_method: ConsumptionPaymentMethod- Payment method (STARS or CRYPTO)status: InvoiceStatus- Invoice status (PENDING, PAID, EXPIRED, CANCELLED)id: Optional[UUID]- Unique invoice identifierexpires_at: Optional[datetime]- Expiration timestamp (30 minutes)paid_at: Optional[datetime]- Payment timestamptransaction_hash: Optional[str]- Transaction hash (crypto)telegram_payment_id: Optional[str]- Telegram payment ID (Stars)created_at: datetime- Creation timestamp
Properties:
is_pending: bool- True if status is PENDINGis_paid: bool- True if status is PAIDis_expired: bool- True if invoice is expiredis_usdt_payment: bool- True if wallet starts with "0x"time_remaining_seconds: int- Seconds remaining to paytime_remaining_formatted: str- Formatted time (MM:SS)
Methods:
mark_as_paid(transaction_hash, telegram_payment_id)- Mark as paidmark_as_expired()- Mark as expiredget_payment_instructions() -> str- Get payment instructionsget_stars_amount() -> int- Get amount in Stars (1 USDT = 120 Stars)get_formatted_amount() -> str- Get formatted amount string
Example:
from usipipo_commons.domain.entities import ConsumptionInvoice
from usipipo_commons.domain.enums import ConsumptionPaymentMethod, InvoiceStatus
from datetime import datetime, timezone
from decimal import Decimal
import uuid
invoice = ConsumptionInvoice(
billing_id=uuid.uuid4(),
user_id=123456789,
amount_usd=Decimal("5.50"),
wallet_address="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
payment_method=ConsumptionPaymentMethod.CRYPTO,
)
print(f"Amount: {invoice.get_formatted_amount()}") # "$5.50 USD"
print(f"Time remaining: {invoice.time_remaining_formatted}") # "29:45"
print(invoice.get_payment_instructions())
Data Package Entities
DataPackage
Represents a purchased data package.
Properties:
user_id: UUID- User IDpackage_type: PackageType- Package type (BASIC, ESTANDAR, AVANZADO, PREMIUM, UNLIMITED)data_limit_bytes: int- Data limit in bytesstars_paid: int- Stars paid for packageexpires_at: datetime- Package expiration dateid: Optional[UUID]- Unique package identifierdata_used_bytes: int- Data consumed in bytespurchased_at: Optional[datetime]- Purchase timestampis_active: bool- Whether package is activetelegram_payment_id: Optional[str]- Telegram payment ID
Properties:
remaining_bytes: int- Remaining data in bytesis_expired: bool- True if package is expiredis_valid: bool- True if active and not expired
Methods:
add_usage(bytes_used: int)- Add data usagedeactivate()- Deactivate the package
Example:
from usipipo_commons.domain.entities import DataPackage, PackageType
from datetime import datetime, timezone, timedelta
import uuid
package = DataPackage(
user_id=uuid.uuid4(),
package_type=PackageType.PREMIUM,
data_limit_bytes=50 * 1024**3, # 50 GB
stars_paid=5000,
expires_at=datetime.now(timezone.utc) + timedelta(days=30),
)
print(f"Remaining: {package.remaining_bytes / 1024**3:.2f} GB")
print(f"Valid: {package.is_valid}")
package.add_usage(5 * 1024**3) # 5 GB used
Admin Entities
AdminUserInfo
Administrative user information for admin panels.
Properties:
user_id: UUID- User IDusername: Optional[str]- Telegram usernamefirst_name: str- First namelast_name: Optional[str]- Last nametotal_keys: int- Total VPN keys ownedactive_keys: int- Active VPN keys countstars_balance: int- Stars balance (deprecated, for compatibility)total_deposited: int- Total deposited (referral credits)referral_credits: int- Referral credits earnedregistration_date: Optional[datetime]- Registration datelast_activity: Optional[datetime]- Last activity timestamp
Example:
from usipipo_commons.domain.entities import AdminUserInfo
from datetime import datetime, timezone
import uuid
admin_user = AdminUserInfo(
user_id=uuid.uuid4(),
username="johndoe",
first_name="John",
last_name="Doe",
total_keys=5,
active_keys=3,
referral_credits=25,
registration_date=datetime.now(timezone.utc),
)
AdminKeyInfo
Administrative VPN key information for admin panels.
Properties:
key_id: str- Key identifieruser_id: UUID- Owner's user IDuser_name: str- Owner's usernamekey_type: str- VPN type (outline, wireguard)key_name: str- Key nameaccess_url: Optional[str]- Access URLcreated_at: datetime- Creation timestamplast_used: Optional[datetime]- Last usage timestampdata_limit: int- Data limit in bytesdata_used: int- Data consumed in bytesis_active: bool- Whether key is activeserver_status: str- Server status
Example:
from usipipo_commons.domain.entities import AdminKeyInfo
from datetime import datetime, timezone
import uuid
key_info = AdminKeyInfo(
key_id="key_123",
user_id=uuid.uuid4(),
user_name="johndoe",
key_type="outline",
key_name="Home VPN",
access_url="ss://...",
created_at=datetime.now(timezone.utc),
data_limit=5 * 1024**3,
data_used=1024**3,
is_active=True,
server_status="healthy",
)
ServerStatus
VPN server status information.
Properties:
server_type: str- Server type (outline, wireguard)is_healthy: bool- Whether server is healthytotal_keys: int- Total keys on serveractive_keys: int- Active keys countversion: Optional[str]- Server versionuptime: Optional[str]- Server uptime stringerror_message: Optional[str]- Error message if any
Example:
from usipipo_commons.domain.entities import ServerStatus
status = ServerStatus(
server_type="outline",
is_healthy=True,
total_keys=100,
active_keys=85,
version="1.2.3",
uptime="15d 4h 32m",
)
AdminOperationResult
Result of an administrative operation.
Properties:
success: bool- Whether operation succeededoperation: str- Operation nametarget_id: str- Target entity IDmessage: str- Result messagedetails: Optional[Dict]- Additional detailstimestamp: Optional[datetime]- Operation timestamp
Example:
from usipipo_commons.domain.entities import AdminOperationResult
result = AdminOperationResult(
success=True,
operation="revoke_key",
target_id="key_123",
message="Key revoked successfully",
details={"previous_status": "active"},
)
if result.success:
print(f"Operation {result.operation} completed: {result.message}")
Support Entities
Ticket
Support ticket entity.
Properties:
user_id: UUID- User who created ticketcategory: TicketCategory- Ticket category (VPN_FAIL, PAYMENT, ACCOUNT, OTHER)priority: TicketPriority- Priority (HIGH, MEDIUM, LOW)subject: str- Ticket subjectid: UUID- Unique ticket identifierstatus: TicketStatus- Status (OPEN, RESPONDED, RESOLVED, CLOSED)created_at: datetime- Creation timestampupdated_at: datetime- Last update timestampresolved_at: Optional[datetime]- Resolution timestampresolved_by: Optional[UUID]- Admin who resolvedadmin_notes: Optional[str]- Admin internal notes
Properties:
ticket_number: str- Readable ticket number (T-XXXXXXX)is_open: bool- True if OPEN or RESPONDEDis_resolved: bool- True if RESOLVEDis_closed: bool- True if CLOSED
Methods:
update_status(new_status, admin_id)- Update ticket status
Example:
from usipipo_commons.domain.entities import Ticket, TicketCategory, TicketPriority, TicketStatus
import uuid
ticket = Ticket(
user_id=uuid.uuid4(),
category=TicketCategory.VPN_FAIL,
priority=TicketPriority.HIGH,
subject="Cannot connect to VPN",
)
print(f"Ticket #{ticket.ticket_number}")
print(f"Status: {ticket.status.value}")
# Update status
ticket.update_status(TicketStatus.RESPONDED, admin_id=1)
TicketMessage
Message within a support ticket.
Properties:
ticket_id: UUID- Parent ticket IDfrom_user_id: UUID- Message sender IDmessage: str- Message contentfrom_admin: bool- True if sent by adminid: UUID- Unique message identifiercreated_at: datetime- Message timestamp
Example:
from usipipo_commons.domain.entities import TicketMessage
import uuid
message = TicketMessage(
ticket_id=uuid.uuid4(),
from_user_id=uuid.uuid4(),
message="I'm still having issues connecting",
from_admin=False,
)
Additional Entities
Referral
Represents a referral relationship.
Properties:
referrer_id: UUID- ID of referring userreferred_id: UUID- ID of referred userid: Optional[UUID]- Unique referral identifiercreated_at: Optional[datetime]- Creation timestampis_active: bool- Whether referral is activebonus_applied: bool- Whether bonus was applied
Example:
from usipipo_commons.domain.entities import Referral
from uuid import uuid4
referral = Referral(
referrer_id=uuid4(),
referred_id=uuid4(),
)
Wallet
BSC wallet for crypto payment management.
Properties:
id: UUID- Unique wallet identifieruser_id: UUID- Owner's user IDaddress: str- Wallet addresslabel: Optional[str]- Wallet labelstatus: WalletStatus- Wallet statusbalance_usdt: float- Current balance in USDTcreated_at: datetime- Creation timestampupdated_at: datetime- Last update timestamplast_used_at: Optional[datetime]- Last usage timestamptotal_received_usdt: float- Total received in USDTtransaction_count: int- Number of transactions
Methods:
create(user_id, address, label) -> Wallet- Factory methodupdate_balance(amount_usdt)- Update balancedeactivate()- Deactivate walletactivate()- Activate walletto_dict() -> dict- Convert to dictionary
Example:
from usipipo_commons.domain.entities import Wallet
from usipipo_commons.domain.enums import WalletStatus
from uuid import uuid4
wallet = Wallet.create(
user_id=uuid4(),
address="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
label="Main Wallet",
)
wallet.update_balance(10.0)
print(f"Balance: ${wallet.balance_usdt} USDT")
WalletPool
Pool of reusable expired wallets.
Properties:
id: UUID- Unique pool entry identifierwallet_address: str- Wallet addressoriginal_user_id: UUID- Original owner's IDstatus: WalletStatus- Pool statuscreated_at: datetime- Creation timestampreleased_at: datetime- Release timestampexpires_at: datetime- Expiration timestampreused_by_user_id: Optional[UUID]- Reused by user IDreused_at: Optional[datetime]- Reuse timestampupdated_at: Optional[datetime]- Last update timestamp
Methods:
create(wallet_address, original_user_id, expires_at) -> WalletPool- Factory methodmark_reused(user_id)- Mark as reusedmark_available()- Mark as availableis_expired() -> bool- Check if expiredis_available() -> bool- Check if availableto_dict() -> dict- Convert to dictionary
Example:
from usipipo_commons.domain.entities import WalletPool
from datetime import datetime, timezone, timedelta
from uuid import uuid4
pool_entry = WalletPool.create(
wallet_address="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
original_user_id=uuid4(),
expires_at=datetime.now(timezone.utc) + timedelta(days=7),
)
if pool_entry.is_available():
pool_entry.mark_reused(uuid4())
Enums Reference
KeyType
VPN key types supported by the system.
class KeyType(str, Enum):
OUTLINE = "outline"
WIREGUARD = "wireguard"
KeyStatus
VPN key status values.
class KeyStatus(str, Enum):
ACTIVE = "active"
EXPIRED = "expired"
REVOKED = "revoked"
PENDING = "pending"
PaymentStatus
Payment transaction status values.
class PaymentStatus(str, Enum):
PENDING = "pending"
COMPLETED = "completed"
FAILED = "failed"
EXPIRED = "expired"
PaymentMethod
Supported payment methods.
class PaymentMethod(str, Enum):
TELEGRAM_STARS = "telegram_stars"
CRYPTO_USDT = "crypto_usdt"
CRYPTO_BSC = "crypto_bsc"
BillingStatus
Consumption billing cycle status values.
class BillingStatus(str, Enum):
ACTIVE = "active" # Cycle in progress, consuming
CLOSED = "closed" # Cycle closed, awaiting payment
PAID = "paid" # Cycle paid, completed
CANCELLED = "cancelled" # Cycle cancelled
InvoiceStatus
Consumption invoice status values.
class InvoiceStatus(str, Enum):
PENDING = "pending" # Invoice generated, awaiting payment
PAID = "paid" # Invoice paid successfully
EXPIRED = "expired" # Invoice expired
CANCELLED = "cancelled" # Invoice manually cancelled
ConsumptionPaymentMethod
Payment methods for consumption invoices.
class ConsumptionPaymentMethod(str, Enum):
STARS = "stars" # Payment with Telegram Stars
CRYPTO = "crypto" # Payment with USDT (BSC)
CryptoOrderStatus
Cryptocurrency order status values.
class CryptoOrderStatus(str, Enum):
PENDING = "pending"
COMPLETED = "completed"
FAILED = "failed"
EXPIRED = "expired"
CryptoTransactionStatus
Cryptocurrency transaction status values.
class CryptoTransactionStatus(str, Enum):
PENDING = "pending"
CONFIRMED = "confirmed"
FAILED = "failed"
PlanType
Subscription plan types.
class PlanType(str, Enum):
ONE_MONTH = "one_month"
THREE_MONTHS = "three_months"
SIX_MONTHS = "six_months"
WalletStatus
BSC wallet status values.
class WalletStatus(str, Enum):
ACTIVE = "active"
INACTIVE = "inactive"
AVAILABLE = "available"
IN_USE = "in_use"
PackageType
Data package types available.
class PackageType(str, Enum):
BASIC = "basic"
ESTANDAR = "estandar"
AVANZADO = "avanzado"
PREMIUM = "premium"
UNLIMITED = "unlimited"
TicketCategory
Support ticket categories.
class TicketCategory(str, Enum):
VPN_FAIL = "vpn_fail"
PAYMENT = "payment"
ACCOUNT = "account"
OTHER = "other"
TicketPriority
Ticket priority levels.
class TicketPriority(str, Enum):
HIGH = "high"
MEDIUM = "medium"
LOW = "low"
TicketStatus
Ticket status values.
class TicketStatus(str, Enum):
OPEN = "open"
RESPONDED = "responded"
RESOLVED = "resolved"
CLOSED = "closed"
Constants
Plan Constants
from usipipo_commons.constants import (
FREE_GB, # 5.0 - Free tier data allowance (GB)
FREE_KEYS_LIMIT, # 2 - Maximum free VPN keys per user
WELCOME_BONUS_GB, # 2.0 - Welcome bonus data (GB)
LOYALTY_BONUS_GB, # 1.0 - Loyalty bonus data (GB)
REFERRAL_BONUS_GB, # 5.0 - Referral bonus data (GB)
MAX_KEYS_PER_USER, # 10 - Maximum VPN keys per user
MIN_PACKAGE_GB, # 1.0 - Minimum package size (GB)
MAX_PACKAGE_GB, # 100.0 - Maximum package size (GB)
PRICE_PER_GB, # 0.50 - Price per GB in USD
BILLING_CYCLE_DAYS, # 30 - Billing cycle duration (days)
)
Error Codes
from usipipo_commons.constants import (
# User errors
USER_NOT_FOUND,
USER_ALREADY_EXISTS,
USER_BANNED,
# VPN key errors
VPN_KEY_NOT_FOUND,
VPN_KEY_LIMIT_REACHED,
VPN_KEY_ALREADY_EXISTS,
VPN_KEY_GENERATION_FAILED,
# Payment errors
PAYMENT_NOT_FOUND,
PAYMENT_ALREADY_COMPLETED,
PAYMENT_EXPIRED,
PAYMENT_FAILED,
INSUFFICIENT_BALANCE,
# Referral errors
REFERRAL_CODE_INVALID,
REFERRAL_CODE_ALREADY_USED,
SELF_REFERRAL_NOT_ALLOWED,
# Authentication errors
AUTH_INVALID_TOKEN,
AUTH_TOKEN_EXPIRED,
AUTH_INVALID_TELEGRAM_DATA,
)
Utilities
Validators
from usipipo_commons.utils import (
validate_telegram_id,
validate_referral_code,
validate_vpn_key_name,
)
# Validate Telegram ID
is_valid = validate_telegram_id(123456789) # True
is_valid = validate_telegram_id(-1) # False
# Validate referral code (alphanumeric, 4-16 chars)
is_valid = validate_referral_code("JOHN123") # True
is_valid = validate_referral_code("abc") # False (too short)
# Validate VPN key name (letters, numbers, spaces, dashes, max 50 chars)
is_valid = validate_vpn_key_name("Home VPN") # True
is_valid = validate_vpn_key_name("") # False
Formatters
from usipipo_commons.utils import (
format_bytes,
format_datetime,
format_duration,
)
from datetime import datetime, timezone
# Format bytes to human-readable
print(format_bytes(5.5)) # "5.50 GB"
print(format_bytes(1500.0)) # "1.50 TB"
# Format datetime
now = datetime.now(timezone.utc)
print(format_datetime(now)) # "2026-03-22 12:00:00 UTC"
# Format duration in seconds
print(format_duration(3665)) # "1h 1m"
print(format_duration(125)) # "2m"
Project Structure
usipipo_commons/
├── domain/
│ ├── entities/ # Domain entities
│ │ ├── __init__.py
│ │ ├── user.py
│ │ ├── vpn_key.py
│ │ ├── payment.py
│ │ ├── balance.py
│ │ ├── crypto_order.py
│ │ ├── crypto_transaction.py
│ │ ├── subscription_plan.py
│ │ ├── subscription_transaction.py
│ │ ├── consumption_billing.py
│ │ ├── consumption_invoice.py
│ │ ├── data_package.py
│ │ ├── ticket.py
│ │ ├── ticket_message.py
│ │ ├── admin_user_info.py
│ │ ├── admin_key_info.py
│ │ ├── server_status.py
│ │ ├── admin_operation_result.py
│ │ ├── referral.py
│ │ ├── wallet.py
│ │ └── admin.py
│ ├── enums/ # Shared enumerations
│ │ ├── __init__.py
│ │ ├── key_type.py
│ │ ├── key_status.py
│ │ ├── payment_status.py
│ │ ├── payment_method.py
│ │ ├── billing_status.py
│ │ ├── invoice_status.py
│ │ ├── consumption_payment_method.py
│ │ ├── crypto_order_status.py
│ │ ├── crypto_transaction_status.py
│ │ ├── plan_type.py
│ │ ├── wallet_status.py
│ │ └── ...
│ └── interfaces/ # Repository interfaces
├── schemas/ # Pydantic schemas for API
├── constants/ # Shared constants
│ ├── __init__.py
│ ├── plans.py # Plan limits and bonuses
│ └── errors.py # Error codes
└── utils/ # Utility functions
├── __init__.py
├── validators.py # Validation functions
└── formatters.py # Formatting functions
Development
Setup
# Clone the repository
git clone https://github.com/uSipipo-Team/usipipo-commons.git
cd usipipo-commons
# Install dependencies with uv (recommended)
uv sync --dev
# Or with pip
pip install -e ".[dev]"
Running Tests
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=usipipo_commons --cov-report=html
# Run specific test file
uv run pytest tests/test_entities.py
Code Quality
# Run linter (ruff)
uv run ruff check .
# Run type checker (mypy)
uv run mypy .
# Format code
uv run ruff format .
Pre-commit Hooks
# Install pre-commit hooks
uv run pre-commit install
# Run all hooks
uv run pre-commit run --all-files
Publishing
Build Package
# Build distribution packages
uv build
# Output:
# dist/
# usipipo_commons-0.12.0-py3-none-any.whl
# usipipo_commons-0.12.0.tar.gz
Publish to PyPI
# Publish to PyPI
uv publish
# Or with explicit token
uv publish --token pypi-xxx...
Version Bumping
Follow Semantic Versioning:
- MAJOR (X.0.0): Breaking changes
- MINOR (0.X.0): New features, backward compatible
- PATCH (0.0.X): Bug fixes, backward compatible
Update version in pyproject.toml before publishing.
Contributing
See CONTRIBUTING.md for detailed contribution guidelines.
Quick Start
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
uv run pytest) - Run linters (
uv run ruff check . && uv run mypy .) - Commit with conventional commits
- Push and open a Pull Request
Code Style
- Line Length: 100 characters
- Quote Style: Double quotes
- Indent: 4 spaces
- Type Hints: Required for all public functions
- Testing: 80%+ coverage target
Related Projects
| Project | Description | Status |
|---|---|---|
| usipipo-backend | FastAPI backend API | 🟢 Active |
| usipipo-telegram-bot | Telegram bot | 🟡 Refactoring |
| usipipo-miniapp-web | Telegram Mini App | 🟡 Pending |
| usipipo-landing | Marketing site | 🟢 Production |
| usipipo-vpn-android | Android VPN app | 🟢 Production |
License
MIT © uSipipo Team
See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file usipipo_commons-0.21.0.tar.gz.
File metadata
- Download URL: usipipo_commons-0.21.0.tar.gz
- Upload date:
- Size: 35.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b264a5f4065d1500d657ed34aaa38838ccdfbc41f4cc67787b02214679d2be8
|
|
| MD5 |
5c2ab6ab83d00050d090f563d2a2f1c2
|
|
| BLAKE2b-256 |
5050fd3eeae50618eab1b0ebbb0d8d9fd71378a6f73caa5034b8a28ff9833c13
|
File details
Details for the file usipipo_commons-0.21.0-py3-none-any.whl.
File metadata
- Download URL: usipipo_commons-0.21.0-py3-none-any.whl
- Upload date:
- Size: 45.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d0d6234818aaf77c6c82235b2f3519d7836dc32ca1c9b29deb73f7b4b2d22cc
|
|
| MD5 |
0c39f60300db0d09dc98b4a6adfe31f5
|
|
| BLAKE2b-256 |
0b169f8e0e0eba5c0acb47d68cc8ef440f567b68a1c96312b26865dc89412dac
|