from datetime import datetime from uuid import uuid4 from monero.address import address from sqlalchemy import Column, Integer, BigInteger, DateTime, String from sqlalchemy.sql import func from app.factory import db from app.library.crypto import monero, wownero from app import config def rand_id(): return uuid4().hex class Swap(db.Model): __tablename__ = 'swaps' # Meta id = db.Column(db.String(80), primary_key=True, default=rand_id) date = db.Column(db.DateTime, server_default=func.now()) wow_to_xmr = db.Column(db.Boolean) wow_price_ausd = db.Column(db.Integer) xmr_price_ausd = db.Column(db.Integer) swap_address = db.Column(db.String(150), unique=True) swap_address_index = db.Column(db.Integer, unique=True) return_wow_address = db.Column(db.String(150)) return_xmr_address = db.Column(db.String(150)) completed = db.Column(db.Boolean, default=False) completed_date = db.Column(db.DateTime, nullable=True) # Receive details receive_amount_atomic = db.Column(db.BigInteger) funds_received = db.Column(db.Boolean, default=False) receive_tx_id = db.Column(db.String(150), nullable=True) # Send details fee_amount_atomic = db.Column(db.BigInteger) send_amount_atomic = db.Column(db.BigInteger) send_tx_id = db.Column(db.String(150), nullable=True) funds_sent = db.Column(db.Boolean, default=False) def __repr__(self): return self.id def show_details(self): if self.wow_to_xmr: r = wownero s = monero r_unit = 'WOW' s_unit = 'XMR' else: r = monero s = wownero r_unit = 'XMR' s_unit = 'WOW' receive_amount = r.as_real(r.from_atomic(self.receive_amount_atomic)) send_amount = s.as_real(s.from_atomic(self.send_amount_atomic)) return { 'id': self.id, 'date': self.date, 'wow_to_xmr': self.wow_to_xmr, 'wow_price_ausd': self.wow_price_ausd, 'xmr_price_ausd': self.xmr_price_ausd, 'swap_address': self.swap_address, 'swap_address_index': self.swap_address_index, 'return_wow_address': self.return_wow_address, 'return_xmr_address': self.return_xmr_address, 'completed': self.completed, 'completed_date': self.completed_date, 'receive_amount_atomic': self.receive_amount_atomic, 'funds_received': self.funds_received, 'receive_tx_id': self.receive_tx_id, 'fee_amount_atomic': self.fee_amount_atomic, 'send_amount_atomic': self.send_amount_atomic, 'send_tx_id': self.send_tx_id, 'funds_sent': self.funds_sent, 'receive': f'{receive_amount} {r_unit}', 'send': f'{send_amount} {s_unit}', 'fee': f'{s.as_real(s.from_atomic(self.fee_amount_atomic))} {s_unit}', 'hours_completed': self.hours_elapsed(since_completed=True), 'hours_active': self.hours_elapsed(), 'receive_unit': r_unit, 'send_unit': s_unit } def hours_elapsed(self, since_completed=False): now = datetime.utcnow() if since_completed: if self.completed_date: diff = now - self.completed_date else: return 0 else: diff = now - self.date return diff.total_seconds() / 60 / 60 def days_completed(self): if self.completed_date: now = datetime.now() diff = now - self.completed_date return diff.days else: return 0 def receive_coin(self): if self.wow_to_xmr: return 'wow' else: return 'xmr' def send_coin(self): if self.wow_to_xmr: return 'xmr' else: return 'wow' def to_ausd(self, amount): return int(amount * 1000000) def from_ausd(self, amount): return amount / 1000000 def validate_swap_worth(self, worth): worth_ausd = self.to_ausd(worth) min = self.to_ausd(config.SWAP_MIN_USD) max = self.to_ausd(config.SWAP_MAX_USD) if worth_ausd < min: return (False, 'Too low') elif worth_ausd > max: return (False, 'Too high') else: return (True, '') def validate_wow_address(self, wow_address): # lol yolo if len(wow_address) != 97: return False else: return True def validate_xmr_address(self, xmr_address): try: address(xmr_address) return True except: return False