pluto/handler/commands.py

433 lines
16 KiB
Python
Raw Normal View History

2021-12-28 12:50:19 +00:00
# Other library imports
2022-01-23 17:07:53 +00:00
from json import dumps, loads
2021-12-28 12:50:19 +00:00
2022-01-23 17:07:53 +00:00
# Project imports
from settings import settings
2021-12-28 12:50:19 +00:00
2021-12-28 12:50:19 +00:00
class IRCCommands(object):
class trades(object):
name = "trades"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Get all open trades."
2021-12-28 12:50:19 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
"""
Get details of open trades and post on IRC.
"""
2021-12-31 18:21:27 +00:00
# Send IRC - we don't want to automatically send messages on IRC, even though
# this variable seems counter-intuitive here, we are doing something with the result
# then calling msg() ourselves, and we don't want extra spam in the channel.
2022-01-09 22:11:39 +00:00
trades = agora.get_dashboard()
2021-12-28 12:50:19 +00:00
if not trades:
msg("No open trades.")
2021-12-28 14:10:05 +00:00
return
2021-12-28 12:50:19 +00:00
for trade_id in trades:
msg(trade_id)
class create(object):
name = "create"
authed = True
2022-01-23 17:07:53 +00:00
helptext = "Create an ad. Usage: create <XMR/BTC> <country> <currency>"
2021-12-28 12:50:19 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
"""
Post an ad on AgoraDesk with the given country and currency code.
"""
2022-01-21 13:54:47 +00:00
if length == 4:
if spl[1] not in loads(settings.Agora.AssetList):
msg(f"Not a valid asset: {spl[1]}")
return
posted = agora.create_ad(spl[1], spl[2], spl[3])
if posted["success"]:
msg(f"{posted['response']['data']['message']}: {posted['response']['data']['ad_id']}")
else:
msg(dumps(posted["response"]))
2021-12-28 12:50:19 +00:00
class messages(object):
name = "messages"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Get messages. Usage: messages [<reference>]"
2021-12-28 12:50:19 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
"""
Get all messages for all open trades or a given trade.
"""
if length == 1:
messages = agora.get_recent_messages()
2021-12-28 14:10:05 +00:00
if messages is False:
msg("Error getting messages.")
return
2021-12-28 12:50:19 +00:00
if not messages:
msg("No messages.")
2021-12-28 14:10:05 +00:00
return
for reference in messages:
for message in messages[reference]:
msg(f"{reference}: {message[0]} {message[1]}")
2021-12-28 12:50:19 +00:00
msg("---")
elif length == 2:
tx = tx.ref_to_tx(spl[1])
if not tx:
msg(f"No such reference: {spl[1]}")
return
2021-12-28 12:50:19 +00:00
messages = agora.get_messages(spl[1], send_irc=False)
if not messages:
msg("No messages.")
for message in messages:
msg(f"{spl[1]}: {message}")
class dist(object):
name = "dist"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Distribute all our chosen currency and country ad pairs."
2021-12-28 12:50:19 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
# Distribute out our ad to all countries in the config
2021-12-29 19:21:27 +00:00
for x in agora.dist_countries():
if x["success"]:
msg(f"{x['response']['data']['message']}: {x['response']['data']['ad_id']}")
else:
2022-01-23 17:07:53 +00:00
msg(dumps(x["response"]))
2021-12-28 12:50:19 +00:00
# class brute(object):
# name = "brute"
# authed = True
# helptext = "Use a bruteforce algorithm to create all possible currency and country pairs."
#
# @staticmethod
# def run(cmd, spl, length, authed, msg, agora, revolut, tx):
# for x in agora.dist_bruteforce():
# if x["success"]:
# msg(f"{x['response']['data']['message']}: {x['response']['data']['ad_id']}")
# else:
# msg(dumps(x))
#
# class fillblanks(object):
# name = "fillblanks"
# authed = True
# helptext = "Resume a run of brute by getting all our adverts then filling the blanks."
#
# @staticmethod
# def run(cmd, spl, length, authed, msg, agora, revolut, tx):
# for x in agora.bruteforce_fill_blanks():
# if x["success"]:
# msg(f"{x['response']['data']['message']}: {x['response']['data']['ad_id']}")
# else:
# msg(dumps(x))
2021-12-31 00:39:52 +00:00
class stripdupes(object):
name = "stripdupes"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Remove all duplicate adverts."
2021-12-31 00:39:52 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
rtrn = agora.strip_duplicate_ads()
msg(dumps(rtrn))
2021-12-28 12:50:19 +00:00
class find(object):
name = "find"
authed = True
2021-12-31 18:21:27 +00:00
helptext = "Find a transaction. Usage: find <currency> <amount>"
2021-12-28 12:50:19 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
"""
Find a transaction received by Revolut with the given reference and amount.
"""
try:
int(spl[2])
except ValueError:
msg("Amount is not an integer.")
rtrn = tx.find_tx(spl[1], spl[2])
if rtrn == "AMOUNT_INVALID":
msg("Reference found but amount invalid.")
elif not rtrn:
msg("Reference not found.")
else:
return dumps(rtrn)
class accounts(object):
name = "accounts"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Get all account information from Revolut."
2021-12-28 12:50:19 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
accounts = revolut.accounts()
2021-12-28 14:10:05 +00:00
accounts_posted = 0
if accounts is None:
msg("Error getting accounts.")
2021-12-28 12:50:19 +00:00
for account in accounts:
if account["balance"] > 0:
if "name" in account:
name = account["name"]
else:
name = "not_set"
msg(f"{name} {account['currency']}: {account['balance']}")
2021-12-28 14:10:05 +00:00
accounts_posted += 1
if accounts_posted == 0:
msg("No accounts with balances.")
2021-12-28 12:50:19 +00:00
class balance(object):
name = "balance"
2021-12-28 12:50:19 +00:00
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Get total account balance from Revolut in USD."
2021-12-28 12:50:19 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
total_usd = revolut.get_total_usd()
2021-12-28 15:28:56 +00:00
if total_usd is False:
2021-12-28 12:50:19 +00:00
msg("Error getting total balance.")
msg(f"Total: {round(total_usd, 2)}USD")
class total(object):
name = "total"
authed = True
helptext = "Get total account balance from Revolut and Agora."
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
total_usd_revolut = revolut.get_total_usd()
if total_usd_revolut is False:
msg("Error getting Revolut balance.")
return
2022-01-21 13:54:47 +00:00
agora_wallet_xmr = agora.agora.wallet_balance_xmr()
if not agora_wallet_xmr["success"]:
msg("Error getting Agora XMR balance.")
return
2022-01-23 17:07:53 +00:00
agora_wallet_btc = agora.agora.wallet_balance()
2022-01-21 13:54:47 +00:00
if not agora_wallet_btc["success"]:
msg("Error getting Agora BTC balance.")
return
total_xmr_agora = agora_wallet_xmr["response"]["data"]["total"]["balance"]
total_btc_agora = agora_wallet_btc["response"]["data"]["total"]["balance"]
# Get the XMR -> USD exchange rate
xmr_usd = agora.cg.get_price(ids="monero", vs_currencies=["USD"])
2022-01-21 13:54:47 +00:00
# Get the BTC -> USD exchange rate
btc_usd = agora.cg.get_price(ids="bitcoin", vs_currencies=["USD"])
# Convert the Agora XMR total to USD
2022-01-21 13:54:47 +00:00
total_usd_agora_xmr = float(total_xmr_agora) * xmr_usd["monero"]["usd"]
# Convert the Agora BTC total to USD
total_usd_agora_btc = float(total_btc_agora) * btc_usd["bitcoin"]["usd"]
# Add it all up
total_usd_agora = total_usd_agora_xmr + total_usd_agora_btc
total_usd = total_usd_agora + total_usd_revolut
# Convert the total USD price to GBP and SEK
rates = agora.get_rates_all()
price_sek = rates["SEK"] * total_usd
price_usd = total_usd
price_gbp = rates["GBP"] * total_usd
msg(f"SEK: {price_sek} | USD: {price_usd} | GBP: {price_gbp}")
2021-12-28 12:50:19 +00:00
class ping(object):
name = "ping"
authed = False
2021-12-31 00:51:43 +00:00
helptext = "Pong!"
2021-12-28 12:50:19 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg):
msg("Pong!")
2021-12-28 13:41:48 +00:00
class release_url(object):
name = "release_url"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Get release URL for all open trades."
2021-12-28 13:41:48 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
trades = agora.dashboard_release_urls()
if not trades:
msg("No trades.")
for trade in trades:
msg(trade)
2021-12-28 15:28:56 +00:00
class message(object):
name = "msg"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Send a message on a trade. Usage: msg <reference> <message...>"
2021-12-28 15:28:56 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
if length > 2:
full_msg = " ".join(spl[2:])
2021-12-29 14:49:29 +00:00
reference = tx.ref_to_tx(spl[1])
if not reference:
msg(f"No such reference: {spl[1]}")
return
rtrn = agora.agora.contact_message_post(reference, full_msg)
msg(f"Sent {full_msg} to {reference}: {rtrn}")
2021-12-28 23:57:25 +00:00
class refs(object):
name = "refs"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "List all references"
2021-12-28 23:57:25 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
msg(f"References: {', '.join(tx.get_refs())}")
class ref(object):
name = "ref"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Get more information about a reference. Usage: ref <reference>"
2021-12-28 23:57:25 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
if length == 2:
ref_data = tx.get_ref(spl[1])
if not ref_data:
2021-12-29 14:49:29 +00:00
msg(f"No such reference: {spl[1]}")
return
2021-12-28 23:57:25 +00:00
msg(f"{spl[1]}: {dumps(ref_data)}")
class delete(object):
name = "del"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Delete a reference. Usage: del <reference>"
2021-12-28 23:57:25 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
if length == 2:
ref_data = tx.get_ref(spl[1])
if not ref_data:
msg(f"No such reference: {spl[1]}")
return
tx.del_ref(spl[1])
msg(f"Deleted reference: {spl[1]}")
2021-12-29 19:21:27 +00:00
class release(object):
name = "release"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Release funds for a trade. Usage: release <reference>"
2021-12-29 19:21:27 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
if length == 2:
tx = tx.ref_to_tx(spl[1])
if not tx:
msg(f"No such reference: {spl[1]}")
return
rtrn = agora.release_funds(tx)
message = rtrn["message"]
message_long = rtrn["response"]["data"]["message"]
msg(f"{message} - {message_long}")
class nuke(object):
name = "nuke"
authed = True
2021-12-31 00:51:43 +00:00
helptext = "Delete all our adverts."
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
rtrn = agora.nuke_ads()
msg(dumps(rtrn))
class wallet(object):
name = "wallet"
authed = True
2022-01-21 13:54:47 +00:00
helptext = "Get Agora wallet balances."
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
2022-01-21 13:54:47 +00:00
rtrn_xmr = agora.agora.wallet_balance_xmr()
if not rtrn_xmr["success"]:
msg("Error getting XMR wallet details.")
return
rtrn_btc = agora.agora.wallet_balance()
if not rtrn_btc["success"]:
msg("Error getting BTC wallet details.")
return
2022-01-21 13:54:47 +00:00
balance_xmr = rtrn_xmr["response"]["data"]["total"]["balance"]
balance_btc = rtrn_btc["response"]["data"]["total"]["balance"]
msg(f"XMR wallet balance: {balance_xmr}")
msg(f"BTC wallet balance: {balance_btc}")
2022-01-09 14:34:37 +00:00
class pubads(object):
name = "pubads"
authed = True
2022-01-25 11:51:44 +00:00
helptext = "View public adverts. Usage: pubads <XMR/BTC> <currency>"
2022-01-09 14:34:37 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
if length == 3:
asset = spl[1]
if asset not in loads(settings.Agora.AssetList):
msg(f"Not a valid asset: {spl[1]}")
return
currency = spl[2]
rtrn = agora.wrap_public_ads(asset, currency)
2022-01-09 14:34:37 +00:00
for ad in rtrn:
msg(f"({ad[0]}) {ad[1]} {ad[2]} {ad[3]}")
class cheat(object):
name = "cheat"
authed = True
helptext = "Cheat the markets by manipulating our prices to exploit people. Usage: cheat [<XMR/BTC>]"
2022-01-09 14:34:37 +00:00
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
if length == 1:
agora._update_prices()
msg("Running cheat in thread.")
elif length == 2:
asset = spl[1]
if asset not in loads(settings.Agora.AssetList):
msg(f"Not a valid asset: {spl[1]}")
return
if asset == "XMR":
xmr = True
btc = False
elif asset == "BTC":
xmr = False
btc = True
agora._update_prices(xmr=xmr, btc=btc)
msg(f"Running cheat in thread for {asset}.")
2022-01-09 14:34:37 +00:00
class ads(object):
name = "ads"
authed = True
helptext = "Get all our ad regions"
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
ads = agora.enum_ads()
for ad in ads:
msg(f"({ad[0]}) {ad[1]} {ad[2]} {ad[3]}")
class xmr(object):
name = "xmr"
authed = True
helptext = "Get current XMR price."
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
xmr_prices = agora.cg.get_price(ids="monero", vs_currencies=["sek", "usd", "gbp"])
price_sek = xmr_prices["monero"]["sek"]
price_usd = xmr_prices["monero"]["usd"]
price_gbp = xmr_prices["monero"]["gbp"]
msg(f"SEK: {price_sek} | USD: {price_usd} | GBP: {price_gbp}")
class btc(object):
name = "btc"
authed = True
helptext = "Get current BTC price."
@staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
xmr_prices = agora.cg.get_price(ids="bitcoin", vs_currencies=["sek", "usd", "gbp"])
price_sek = xmr_prices["bitcoin"]["sek"]
price_usd = xmr_prices["bitcoin"]["usd"]
price_gbp = xmr_prices["bitcoin"]["gbp"]
msg(f"SEK: {price_sek} | USD: {price_usd} | GBP: {price_gbp}")