This functions, placing swap on POST request, but as I am new to Python, Quart, and Async, and I still have much to learn I know there must be somethings that I could do better, if not that are just plainly wrong. For instance, I am uncertain about where exactly I should use try and except, or if my method to reattempt failed transactions that result in an error is correct: start with 1 second and doubling until reaching 32 and then repeating for nearly 1 hour.
I would really appreciate if those with more experience could review my project and tell me where I could improve it:
import asyncio
from quart import Quart, request
from terra_sdk.client.lcd import AsyncLCDClient
from terra_sdk.key.mnemonic import MnemonicKey
from terra_sdk.core.market import MsgSwap
import json, config, urllib
from urllib.request import Request
app = Quart(__name__)
mk = MnemonicKey(mnemonic=config.MNEMONIC)
account = mk.acc_address
@app.before_serving
async def startup():
app.terra = AsyncLCDClient("https://bombay.stakesystems.io/", "bombay-12") # https://bombay-lcd.terra.dev
app.wallet = app.terra.wallet(mk)
@app.route('/webhook', methods=['POST'])
async def webhook():
data = json.loads(await request.data)
if (data['passphrase']) != config.WEBHOOK_PASSPHRASE: #Upgrade to bcrypt.
return {
"code": "error",
"message": "invalid passphrase"
}
coins = await app.terra.bank.balance(account)
denoms = coins.denoms()
if 'uluna' in denoms:
base = coins['uluna']
base_amount = base.amount
else:
base = None
base_amount = 0
if 'uusd' in denoms:
quote = coins['uusd']
quote_amount = quote.amount
else:
quote = None
quote_amount = 0
action = data['strategy']['order_action']
print("\n")
print(f"LUNA: \t\t{base_amount/10**6}")
print(f"UST: \t\t{quote_amount/10**6}")
print(f"Action: \t{action.upper()}")
print("\n")
if ( (action == 'buy' and quote_amount > 100000000) or (action == 'sell' and base_amount > 0) ):
result = await swap( ( base, quote - 100000000)[action == 'buy'], ( 'uusd', 'uluna')[action == 'buy'] )
if result:
print('Swap complete.')
return {
"code": "success",
"message": "swap complete"
}
else:
print('Swap failure.')
return {
"code": "error",
"message": "swap failure" }
else:
print('Insufficient funds.')
return {
"code": "response",
"message": "insufficient funds"
}
async def swap( offer_coin, ask_denom ):
print (f'Swapping {offer_coin.denom} for {ask_denom}.')
swap = MsgSwap(mk.acc_address, offer_coin, ask_denom )
url_request = Request("https://fcd.terra.dev/v1/txs/gas_prices", headers={"User-Agent": "Mozilla/5.0"})
live_gas_prices = json.loads(urllib.request.urlopen(url_request).read().decode())
tx = await app.wallet.create_and_sign_tx(
msgs = [swap],
gas_prices = live_gas_prices,
gas_adjustment = '1.5',
fee_denoms = ['uusd']
)
tx_error = True
delay = 1
count = 0
while tx_error and count < 100:
result = await app.terra.tx.broadcast(tx)
print(result)
print(result.gas_used)
tx_error = result.is_tx_error()
print(f"\nError: {tx_error}")
count = count + 1
if tx_error == True:
print(f"\nCount: {count}")
await asyncio.sleep(delay)
if count <= 5:
delay = (delay * 2)
gas_used = result.gas_used
return not tx_error
if __name__ == "__main__":
app.run()