# Twisted/Klein imports from twisted.logger import Logger from twisted.internet.task import LoopingCall # Other library imports from json import loads from forex_python.converter import CurrencyRates from agoradesk_py.agoradesk import AgoraDesk # Project imports from settings import settings class Agora(object): """ AgoraDesk API handler. """ def __init__(self): """ Initialise the AgoraDesk and CurrencyRates APIs. Initialise the last_dash storage for detecting new trades. """ self.log = Logger("agora") self.agora = AgoraDesk(settings.Agora.Token) self.cr = CurrencyRates() self.last_dash = set() def set_irc(self, irc): self.irc = irc def setup_loop(self): """ Set up the LoopingCall to get all active trades. """ self.lc = LoopingCall(self.dashboard) self.lc.start(int(settings.Agora.RefreshSec)) def dashboard_id_only(self): """ Returns a list of the IDs of open trades. :return: list of open trade IDs :rtype: list """ dash = self.agora.dashboard_seller() dash_tmp = [] if dash["response"]["data"]["contact_count"] > 0: for contact in dash["response"]["data"]["contact_list"]: contact_id = contact["data"]["contact_id"] dash_tmp.append(contact_id) return dash_tmp def dashboard(self): """ Get information about our open trades. :return: human readable list of strings about our trades :rtype: list """ dash = self.agora.dashboard_seller() dash_tmp = [] if dash["response"]["data"]["contact_count"] > 0: for contact in dash["response"]["data"]["contact_list"]: contact_id = contact["data"]["contact_id"] buyer = contact["data"]["buyer"]["username"] amount = contact["data"]["amount"] amount_xmr = contact["data"]["amount_xmr"] currency = contact["data"]["currency"] if not contact["data"]["is_selling"]: continue if contact_id not in self.last_dash: self.irc.client.msg(self.irc.client.channel, f"{contact_id}: {buyer} {amount}{currency} {amount_xmr}XMR") dash_tmp.append(f"{contact_id}: {buyer} {amount}{currency} {amount_xmr}XMR") self.last_dash.add(contact_id) return dash_tmp def get_messages(self, contact_id): """ Get messages for a certain trade ID. :param contact_id: trade/contact ID :return: list of messages :rtype: list """ messages = self.agora.contact_messages(contact_id) messages_tmp = [] for message in messages["response"]["data"]["message_list"]: messages_tmp.append(f"({message['sender']['username']}): {message['msg']}") return messages_tmp def get_all_messages(self): """ Get all messages for all open trades. :return: dict of lists keyed by trade/contact ID :rtype: dict with lists """ dash = self.dashboard_id_only() messages_tmp = {} for contact_id in dash: messages = self.get_messages(contact_id) messages_tmp[contact_id] = messages return messages_tmp def get_ads(self): """ Get information about our ads. :return: data about our open ads :rtype: dict """ ads = self.agora.ads() return ads def get_rates_all(self): """ Get all rates that pair with USD. :return: dictionary of USD/XXX rates :rtype: dict """ rates = self.cr.get_rates("USD") return rates def create_ad(self, countrycode, currency): """ Post an ad in a country with a given currency. Convert the min and max amounts from settings to the given currency with CurrencyRates. :param countrycode: country code :param currency: currency code :type countrycode: string :type currency: string :return: data about created object or error :rtype: dict """ rates = self.get_rates_all() if currency == "USD": min_amount = float(settings.Agora.MinUSD) max_amount = float(settings.Agora.MaxUSD) else: min_amount = rates[currency] * float(settings.Agora.MinUSD) max_amount = rates[currency] * float(settings.Agora.MaxUSD) price_formula = f"coingeckoxmrusd*usd{currency.lower()}*{settings.Agora.Margin}" # price_formula = f"coingeckoxmrusd*{settings.Agora.Margin}" ad = settings.Agora.Ad ad = ad.replace("\\t", "\t") ad = self.agora.ad_create( country_code=countrycode, currency=currency, trade_type="ONLINE_SELL", asset="XMR", price_equation=price_formula, track_max_amount=False, require_trusted_by_advertiser=False, # verified_email_required = False, online_provider="REVOLUT", msg=settings.Agora.Ad, min_amount=min_amount, max_amount=max_amount, payment_method_details=settings.Agora.PaymentMethodDetails, # require_feedback_score = 0, account_info=settings.Agora.PaymentDetails, ) return ad def dist_countries(self): """ Distribute our advert into all countries listed in the config. :return: True or False :rtype: bool """ for currency, countrycode in loads(settings.Agora.DistList): rtrn = self.create_ad(countrycode, currency) if not rtrn: return False return True