diff --git a/account.py b/account.py index 76892af..2ad1d7a 100644 --- a/account.py +++ b/account.py @@ -10,10 +10,8 @@ import time dotenv.load_dotenv() -HSD_API = os.getenv("HSD_API") -HSD_IP = os.getenv("HSD_IP") -if HSD_IP is None: - HSD_IP = "localhost" +HSD_API = os.getenv("HSD_API","") +HSD_IP = os.getenv("HSD_IP","localhost") HSD_NETWORK = os.getenv("HSD_NETWORK") HSD_WALLET_PORT = 12039 @@ -47,9 +45,7 @@ cacheTime = 3600 # Verify the connection response = hsd.getInfo() -EXCLUDE = ["primary"] -if os.getenv("EXCLUDE") is not None: - EXCLUDE = os.getenv("EXCLUDE").split(",") +EXCLUDE = os.getenv("EXCLUDE","primary").split(",") def hsdConnected(): @@ -68,7 +64,7 @@ def hsdVersion(format=True): return info['version'] -def check_account(cookie: str): +def check_account(cookie: str | None): if cookie is None: return False @@ -84,7 +80,12 @@ def check_account(cookie: str): return account -def check_password(cookie: str, password: str): +def check_password(cookie: str|None, password: str|None): + if cookie is None: + return False + if password is None: + password = "" + account = check_account(cookie) if account == False: return False @@ -403,17 +404,30 @@ def check_hip2(domain: str): return 'Invalid domain' address = domainLookup.hip2(domain) - if address.startswith("Hip2: "): + if not address.startswith("Hip2: "): + if not check_address(address, False, True): + return 'Hip2: Lookup succeeded but address is invalid' return address - + # Try using WALLET TXT record + address = domainLookup.wallet_txt(domain) + if not address.startswith("hs1"): + return "No HIP2 or WALLET record found for this domain" if not check_address(address, False, True): - return 'Hip2: Lookup succeeded but address is invalid' + return 'WALLET DNS record found but address is invalid' return address + + def send(account, address, amount): account_name = check_account(account) password = ":".join(account.split(":")[1:]) + if not account_name: + return { + "error": { + "message": "Invalid account" + } + } response = hsw.rpc_selectWallet(account_name) if response['error'] is not None: return { @@ -718,9 +732,13 @@ def getPendingFinalizes(account, password): pending = [] try: for output in tx['outputs']: - if output['covenant']['type'] != 10: + if type(output) != dict: continue - if output['covenant']['action'] != "FINALIZE": + if not 'covenant' in output: + continue + if output['covenant'].get("type") != 10: + continue + if output['covenant'].get('action') != "FINALIZE": continue nameHash = output['covenant']['items'][0] # Try to get the name from hash diff --git a/domainLookup.py b/domainLookup.py index 8ac30a7..353a61e 100644 --- a/domainLookup.py +++ b/domainLookup.py @@ -6,10 +6,14 @@ import subprocess import binascii import datetime import dns.asyncresolver +import dns.message +import dns.query +import dns.rdatatype import httpx from requests_doh import DNSOverHTTPSSession, add_dns_provider import requests import urllib3 +from cryptography.x509.oid import ExtensionOID urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # Disable insecure request warnings (since we are manually verifying the certificate) @@ -56,7 +60,7 @@ def hip2(domain: str): domains = [] for ext in cert_obj.extensions: - if ext.oid == x509.ExtensionOID.SUBJECT_ALTERNATIVE_NAME: + if ext.oid == ExtensionOID.SUBJECT_ALTERNATIVE_NAME: san_list = ext.value.get_values_for_type(x509.DNSName) domains.extend(san_list) @@ -120,13 +124,39 @@ def hip2(domain: str): print(f"Hip2: Lookup failed with error: {e}",flush=True) return "Hip2: Lookup failed." +def wallet_txt(domain: str, doh_url="https://hnsdoh.com/dns-query"): + with httpx.Client() as client: + q = dns.message.make_query(domain, dns.rdatatype.from_text("TYPE262")) + r = dns.query.https(q, doh_url, session=client) + + if not r.answer: + return "No wallet address found for this domain" + + wallet_record = "No WALLET record found" + for ans in r.answer: + raw = ans[0].to_wire() # type: ignore + try: + data = raw[1:].decode("utf-8", errors="ignore") + except UnicodeDecodeError: + return f"Unknown WALLET record format: {raw.hex()}" + + if data.startswith("HNS:"): + wallet_record = data[4:] + break + elif data.startswith("HNS "): + wallet_record = data[4:] + break + elif data.startswith('"HNS" '): + wallet_record = data[6:].strip('"') + break + return wallet_record def resolve_with_doh(query_name, doh_url="https://hnsdoh.com/dns-query"): with httpx.Client() as client: q = dns.message.make_query(query_name, dns.rdatatype.A) r = dns.query.https(q, doh_url, session=client) - ip = r.answer[0][0].address + ip = r.answer[0][0].address # type: ignore return ip def resolve_TLSA_with_doh(query_name, doh_url="https://hnsdoh.com/dns-query"): diff --git a/main.py b/main.py index 01f5241..5741698 100644 --- a/main.py +++ b/main.py @@ -66,7 +66,6 @@ def index(): # Check if the user is logged in if request.cookies.get("account") is None: return redirect("/login") - account = account_module.check_account(request.cookies.get("account")) if not account: return redirect("/logout") @@ -114,7 +113,7 @@ def transactions(): return redirect("/logout") # Get the page parameter - page = request.args.get('page') + page = request.args.get('page', 1) try: page = int(page) except: @@ -135,6 +134,8 @@ def send_page(): return redirect("/login") account = account_module.check_account(request.cookies.get("account")) + if not account: + return redirect("/logout") max = account_module.getBalance(account)['available'] # Subtract approx fee max = max - fees @@ -170,28 +171,28 @@ def send(): amount = request.form.get("amount") if address is None or amount is None: - return redirect("/send?message=Invalid address or amount&address=" + address + "&amount=" + amount) + return redirect(f"/send?message=Invalid address or amount&address={address}&amount={amount}") address_check = account_module.check_address(address.strip(),True,True) if not address_check: - return redirect("/send?message=Invalid address&address=" + address + "&amount=" + amount) + return redirect(f"/send?message=Invalid address&address={address}&amount={amount}") address = address_check # Check if the amount is valid if re.match(r"^\d+(\.\d+)?$", amount) is None: - return redirect("/send?message=Invalid amount&address=" + address + "&amount=" + amount) + return redirect(f"/send?message=Invalid amount&address={address}&amount={amount}") # Check if the amount is valid amount = float(amount) if amount <= 0: - return redirect("/send?message=Invalid amount&address=" + address + "&amount=" + str(amount)) + return redirect(f"/send?message=Invalid amount&address={address}&amount={amount}") if amount > account_module.getBalance(account)['available'] - fees: - return redirect("/send?message=Not enough funds to transfer&address=" + address + "&amount=" + str(amount)) + return redirect(f"/send?message=Not enough funds to transfer&address={address}&amount={amount}") toAddress = address if request.form.get('address') != address: - toAddress = request.form.get('address') + "
" + address + toAddress = f"{request.form.get('address')}
{address}" action = f"Send HNS to {request.form.get('address')}" content = f"Are you sure you want to send {amount} HNS to {toAddress}

" @@ -202,7 +203,6 @@ def send(): return render_template("confirm.html", account=account_module.check_account(request.cookies.get("account")), - action=action, content=content,cancel=cancel,confirm=confirm) @@ -211,20 +211,20 @@ def send(): def sendConfirmed(): address = request.args.get("address") - amount = float(request.args.get("amount")) + amount = float(request.args.get("amount","0")) response = account_module.send(request.cookies.get("account"),address,amount) if 'error' in response and response['error'] != None: # If error is a dict get the message if isinstance(response['error'], dict): if 'message' in response['error']: - return redirect("/send?message=" + response['error']['message'] + "&address=" + address + "&amount=" + str(amount)) + return redirect(f"/send?message={response['error']['message']}&address={address}&amount={amount}") else: - return redirect("/send?message=" + str(response['error']) + "&address=" + address + "&amount=" + str(amount)) + return redirect(f"/send?message={response['error']}&address={address}&amount={amount}") # If error is a string - return redirect("/send?message=" + response['error'] + "&address=" + address + "&amount=" + str(amount)) + return redirect(f"/send?message={response['error']}&address={address}&amount={amount}") - return redirect("/success?tx=" + response['tx']) + return redirect(f"/success?tx={response['tx']}") @@ -363,6 +363,9 @@ def revealAllBids(): return redirect("/logout") response = account_module.revealAll(request.cookies.get("account")) + if not response: + return redirect("/auctions?message=Failed to reveal bids") + if 'error' in response: if response['error'] != None: if response['error']['message'] == "Nothing to do.": @@ -383,6 +386,9 @@ def redeemAllBids(): return redirect("/logout") response = account_module.redeemAll(request.cookies.get("account")) + if not response: + return redirect("/auctions?message=Failed to redeem bids") + if 'error' in response: if response['error'] != None: if response['error']['message'] == "Nothing to do.": @@ -402,13 +408,16 @@ def registerAllDomains(): return redirect("/logout") response = account_module.registerAll(request.cookies.get("account")) + if not response: + return redirect("/auctions?message=Failed to register domains") + if 'error' in response: if response['error'] != None: if response['error']['message'] == "Nothing to do.": return redirect("/auctions?message=No domains to register") return redirect("/auctions?message=" + response['error']['message']) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/success?tx={response['hash']}") @app.route('/all/finalize') def finalizeAllBids(): @@ -427,7 +436,7 @@ def finalizeAllBids(): return redirect("/dashboard?message=No domains to finalize") return redirect("/dashboard?message=" + response['error']['message']) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/success?tx={response['hash']}") #endregion @app.route('/search') @@ -441,6 +450,8 @@ def search(): return redirect("/logout") search_term = request.args.get("q") + if search_term is None: + return redirect("/") search_term = search_term.lower().strip() # Replace spaces with hyphens @@ -457,7 +468,7 @@ def search(): # Execute domain plugins searchFunctions = plugins_module.getSearchFunctions() for function in searchFunctions: - functionOutput = plugins_module.runPluginFunction(function["plugin"],function["function"],{"domain":search_term},account_module.check_account(request.cookies.get("account"))) + functionOutput = plugins_module.runPluginFunction(function["plugin"],function["function"],{"domain":search_term},account) plugins += render.plugin_output(functionOutput,plugins_module.getPluginFunctionReturns(function["plugin"],function["function"])) plugins += "" @@ -475,6 +486,7 @@ def search(): state = domain['info']['state'] stats = domain['info']['stats'] + next = "" if state == 'CLOSED': if domain['info']['registered']: state = 'REGISTERED' @@ -571,7 +583,7 @@ def manage(domain: str): # Execute domain plugins domainFunctions = plugins_module.getDomainFunctions() for function in domainFunctions: - functionOutput = plugins_module.runPluginFunction(function["plugin"],function["function"],{"domain":domain},account_module.check_account(request.cookies.get("account"))) + functionOutput = plugins_module.runPluginFunction(function["plugin"],function["function"],{"domain":domain},account) plugins += render.plugin_output(functionOutput,plugins_module.getPluginFunctionReturns(function["plugin"],function["function"])) plugins += "" @@ -676,7 +688,7 @@ def revokeConfirm(domain: str): print(response) return redirect("/manage/" + domain + "?error=" + response['error']['message']) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/success?tx={response['hash']}") @app.route('/manage//renew') def renew(domain: str): @@ -690,7 +702,7 @@ def renew(domain: str): domain = domain.lower() response = account_module.renewDomain(request.cookies.get("account"),domain) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/success?tx={response['hash']}") @app.route('/manage//edit') def editPage(domain: str): @@ -716,8 +728,11 @@ def editPage(domain: str): dns = urllib.parse.unquote(user_edits) else: dns = account_module.getDNS(domain) - - dns = json.loads(dns) + + if dns and isinstance(dns, str): + dns = json.loads(dns) + else: + dns = [] # Check if new records have been added dnsType = request.args.get("type") @@ -733,14 +748,14 @@ def editPage(domain: str): return redirect("/manage/" + domain + "/edit?dns=" + urllib.parse.quote(str(raw_dns)) + "&error=Invalid DS record") try: - ds[0] = int(ds[0]) - ds[1] = int(ds[1]) - ds[2] = int(ds[2]) + key_tag = int(ds[0]) + algorithm = int(ds[1]) + digest_type = int(ds[2]) except: raw_dns = str(dns).replace("'",'"') return redirect("/manage/" + domain + "/edit?dns=" + urllib.parse.quote(str(raw_dns)) + "&error=Invalid DS record") - finally: - dns.append({"type": dnsType, "keyTag": ds[0], "algorithm": ds[1], "digestType": ds[2], "digest": ds[3]}) + + dns.append({"type": dnsType, "keyTag": key_tag, "algorithm": algorithm, "digestType": digest_type, "digest": ds[3]}) dns = json.dumps(dns).replace("'",'"') return redirect("/manage/" + domain + "/edit?dns=" + urllib.parse.quote(dns)) @@ -770,13 +785,15 @@ def editSave(domain: str): domain = domain.lower() dns = request.args.get("dns") + if dns is None: + return redirect(f"/manage/{domain}/edit?error=No DNS records provided") raw_dns = dns dns = urllib.parse.unquote(dns) response = account_module.setDNS(request.cookies.get("account"),domain,dns) if 'error' in response: print(response) - return redirect("/manage/" + domain + "/edit?dns="+raw_dns+"&error=" + str(response['error'])) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/manage/{domain}/edit?dns={raw_dns}&error={response['error']}") + return redirect(f"/success?tx={response['hash']}") @app.route('/manage//transfer') def transfer(domain): @@ -801,7 +818,7 @@ def transfer(domain): toAddress = address if request.form.get('address') != address: - toAddress = request.args.get('address') + "
" + address + toAddress = f"{request.args.get('address')}
{address}" action = f"Send {domain}/ to {request.form.get('address')}" content = f"Are you sure you want to send {domain}/ to {toAddress}

" @@ -811,9 +828,7 @@ def transfer(domain): confirm = f"/manage/{domain}/transfer/confirm?address={address}" - return render_template("confirm.html", account=account_module.check_account(request.cookies.get("account")), - - action=action, + return render_template("confirm.html", account=account,action=action, content=content,cancel=cancel,confirm=confirm) @app.route('/manage//sign') @@ -836,7 +851,7 @@ def signMessage(domain): signedMessage = account_module.signMessage(request.cookies.get("account"),domain,message) if signedMessage["error"] != None: return redirect("/manage/" + domain + "?error=" + signedMessage["error"]) - content += "Signature:
" + signedMessage["result"] + "

" + content += f"Signature:
{signedMessage["result"]}

" data = { "domain": domain, @@ -853,8 +868,7 @@ def signMessage(domain): - return render_template("message.html", account=account, - + return render_template("message.html", account=account, title="Sign Message",content=content) @@ -873,7 +887,7 @@ def transferConfirm(domain): if 'error' in response: return redirect("/manage/" + domain + "?error=" + response['error']) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/success?tx={response['hash']}") @app.route('/auction/') @@ -917,20 +931,9 @@ def auction(domain): state = domainInfo['info']['state'] next_action = '' + next = "" - # bids = account_module.getBids(account,search_term) bids = [] - # if bids == []: - # bids = "No bids found" - # next_action = f'Rescan Auction' - # else: - # reveals = account_module.getReveals(account,search_term) - # for reveal in reveals: - # # Get TX - # revealInfo = account_module.getRevealTX(reveal) - # reveal['bid'] = revealInfo - # bids = render.bids(bids,reveals) - stats = domainInfo['info']['stats'] if 'stats' in domainInfo['info'] else {} if state == 'CLOSED': if not domainInfo['info']['registered']: @@ -1010,8 +1013,8 @@ def bid(domain): return redirect("/logout") domain = domain.lower() - bid = request.args.get("bid") - blind = request.args.get("blind") + bid = request.args.get("bid","") + blind = request.args.get("blind","") if bid == "": bid = 0 @@ -1056,8 +1059,8 @@ def bid_confirm(domain): return redirect("/logout") domain = domain.lower() - bid = request.args.get("bid") - blind = request.args.get("blind") + bid = request.args.get("bid","") + blind = request.args.get("blind","") if bid == "": bid = 0 @@ -1076,7 +1079,7 @@ def bid_confirm(domain): if 'error' in response: return redirect("/auction/" + domain + "?error=" + response['error']['message']) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/success?tx={response['hash']}") @app.route('/auction//open') def open_auction(domain): @@ -1095,7 +1098,7 @@ def open_auction(domain): if response['error'] != None: return redirect("/auction/" + domain + "?error=" + response['error']['message']) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/success?tx={response['hash']}") @app.route('/auction//reveal') def reveal_auction(domain): @@ -1110,8 +1113,8 @@ def reveal_auction(domain): domain = domain.lower() response = account_module.revealAuction(request.cookies.get("account"),domain) if 'error' in response: - return redirect("/auction/" + domain + "?message=" + response['error']['message']) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/auction/{domain}?message={response['error']}") + return redirect(f"/success?tx={response['hash']}") @app.route('/auction//register') def registerdomain(domain): @@ -1126,7 +1129,7 @@ def registerdomain(domain): response = account_module.register(request.cookies.get("account"),domain) if 'error' in response: return redirect("/auction/" + domain + "?message=" + response['error']['message']) - return redirect("/success?tx=" + response['hash']) + return redirect(f"/success?tx={response['hash']}") #endregion #region Settings @@ -1153,6 +1156,11 @@ def settings(): hsd_version=account_module.hsdVersion(False), error=error,success=success,version="Error") info = gitinfo.get_git_info() + if not info: + return render_template("settings.html", account=account, + hsd_version=account_module.hsdVersion(False), + error=error,success=success,version="Error") + branch = info['refs'] if branch != "main": branch = f"({branch})" @@ -1192,20 +1200,19 @@ def settings_action(action): elif action == "zap": resp = account_module.zapTXs(request.cookies.get("account")) - if 'error' in resp: + if type(resp) == dict and 'error' in resp: return redirect("/settings?error=" + str(resp['error'])) return redirect("/settings?success=Zapped transactions") elif action == "xpub": xpub = account_module.getxPub(request.cookies.get("account")) content = "

" - content += "" + content += f"" content += "" content += "" return render_template("message.html", account=account, - title="xPub Key", - content=""+xpub+"" + content) + content=f"{xpub}{content}") return redirect("/settings?error=Invalid action") @@ -1215,6 +1222,9 @@ def upload_image(): return redirect("/login?message=Not logged in") account = request.cookies.get("account") + account = account_module.check_account(account) + if not account: + return redirect("/logout") if not os.path.exists('user_data/images'): os.mkdir('user_data/images') @@ -1224,11 +1234,12 @@ def upload_image(): file = request.files['image'] if file.filename == '': return redirect("/settings?error=No file selected") - if file: - filepath = os.path.join(f'user_data/images/{account.split(":")[0]}.{file.filename.split(".")[-1]}') + if file and file.filename: + filepath = os.path.join(f'user_data/images/{account}.{file.filename.split(".")[-1]}') file.save(filepath) return redirect("/settings?success=File uploaded successfully") + return redirect("/settings?error=An error occurred") def latestVersion(branch): result = requests.get(f"https://git.woodburn.au/api/v1/repos/nathanwoodburn/firewalletbrowser/branches") @@ -1265,6 +1276,12 @@ def login_post(): account = request.form.get("account") password = request.form.get("password") + if account == None or password == None: + wallets = account_module.listWallets() + wallets = render.wallets(wallets) + return render_template("login.html", + error="Invalid account or password",wallets=wallets) + # Check if the account is valid if account.count(":") > 0: wallets = account_module.listWallets() @@ -1280,8 +1297,6 @@ def login_post(): wallets = render.wallets(wallets) return render_template("login.html", error="Invalid account or password",wallets=wallets) - - # Set the cookie response = make_response(redirect("/")) response.set_cookie("account", account) @@ -1300,6 +1315,11 @@ def register(): password = request.form.get("password") repeatPassword = request.form.get("password_repeat") + if account == None or password == None or repeatPassword == None: + return render_template("register.html", + error="Invalid account or password", + name=account,password=password,password_repeat=repeatPassword) + # Check if the passwords match if password != repeatPassword: return render_template("register.html", @@ -1329,10 +1349,8 @@ def register(): # Set the cookie - response = make_response(render_template("message.html", - - title="Account Created", - content="Your account has been created. Here is your seed phrase. Please write it down and keep it safe as it will not be shown again

" + response['seed'])) + response = make_response(render_template("message.html",title="Account Created", + content=f"Your account has been created. Here is your seed phrase. Please write it down and keep it safe as it will not be shown again

{response['seed']}")) response.set_cookie("account", account+":"+password) return response @@ -1344,6 +1362,12 @@ def import_wallet(): repeatPassword = request.form.get("password_repeat") seed = request.form.get("seed") + if account == None or password == None or repeatPassword == None or seed == None: + return render_template("import-wallet.html", + error="Invalid account, password or seed", + name=account,password=password,password_repeat=repeatPassword, + seed=seed) + # Check if the passwords match if password != repeatPassword: return render_template("import-wallet.html", @@ -1560,6 +1584,7 @@ def api_hsd(function): stats = domainInfo['info']['stats'] if 'stats' in domainInfo['info'] else {} state = domainInfo['info']['state'] next_action = "" + next = "" if state == 'CLOSED': if not domainInfo['info']['registered']: if account_module.isOwnDomain(account,domain): @@ -1638,7 +1663,10 @@ def api_wallet(function): return jsonify({"error": "Not logged in"}) account = account_module.check_account(request.cookies.get("account")) - password = request.cookies.get("account").split(":")[1] + if not account: + return jsonify({"error": "Invalid account"}) + + password = request.cookies.get("account","").split(":")[1] if not account: return jsonify({"error": "Invalid account"}) @@ -1672,7 +1700,7 @@ def api_wallet(function): if function == "domains": domains = account_module.getDomains(account) - if 'error' in domains: + if type(domains) == dict and 'error' in domains: return jsonify({"result": [], "error": domains['error']}) # Add nameRender to each domain @@ -1683,7 +1711,7 @@ def api_wallet(function): if function == "transactions": # Get the page parameter - page = request.args.get('page') + page = request.args.get('page', 1) try: page = int(page) except: @@ -1759,7 +1787,7 @@ def api_wallet_mobile(function): return jsonify({"error": "Not logged in"}) account = account_module.check_account(request.cookies.get("account")) - password = request.cookies.get("account").split(":")[1] + password = request.cookies.get("account","").split(":")[1] if not account: return jsonify({"error": "Invalid account"}) @@ -1821,7 +1849,11 @@ def renderDomain(name: str) -> str: #region Assets and default pages @app.route('/qr/') def qr(data): - return send_file(qrcode(data, mode="raw"), mimetype="image/png") + + output = qrcode(data, mode="raw") + if output is None: + return jsonify({"error": "Invalid data"}), 400 + return send_file(output, mimetype="image/png") # Theme @app.route('/assets/css/styles.min.css') diff --git a/plugin.py b/plugin.py index b162a6e..ec4b923 100644 --- a/plugin.py +++ b/plugin.py @@ -148,11 +148,14 @@ def getPluginData(pluginStr: str): def getPluginFunctions(plugin: str): - plugin = import_module(plugin.replace("/",".")) - return plugin.functions + imported_plugin = import_module(plugin.replace("/",".")) + return imported_plugin.functions -def runPluginFunction(plugin: str, function: str, params: dict, authentication: str): +def runPluginFunction(plugin: str, function: str, params: dict, authentication: (str|None)): + if not authentication: + return {"error": "Authentication required"} + plugin_module = import_module(plugin.replace("/",".")) if function not in plugin_module.functions: return {"error": "Function not found"} @@ -189,13 +192,13 @@ def runPluginFunction(plugin: str, function: str, params: dict, authentication: def getPluginFunctionInputs(plugin: str, function: str): - plugin = import_module(plugin.replace("/",".")) - return plugin.functions[function]["params"] + imported_plugin = import_module(plugin.replace("/",".")) + return imported_plugin.functions[function]["params"] def getPluginFunctionReturns(plugin: str, function: str): - plugin = import_module(plugin.replace("/",".")) - return plugin.functions[function]["returns"] + imported_plugin = import_module(plugin.replace("/",".")) + return imported_plugin.functions[function]["returns"] def getDomainFunctions(): diff --git a/render.py b/render.py index a0be33f..0ddf765 100644 --- a/render.py +++ b/render.py @@ -7,10 +7,8 @@ import os from handywrapper import api import threading -HSD_API = os.getenv("HSD_API") -HSD_IP = os.getenv("HSD_IP") -if HSD_IP is None: - HSD_IP = "localhost" +HSD_API = os.getenv("HSD_API","") +HSD_IP = os.getenv("HSD_IP","localhost") HSD_NETWORK = os.getenv("HSD_NETWORK") HSD_WALLET_PORT = 12039 @@ -560,7 +558,6 @@ def renderDomainAsync(namehash: str) -> None: if namehash in cache: return - # Fetch the name outside the lock (network call) name = hsd.rpc_getNameByHash(namehash) if name["error"] is None: @@ -576,7 +573,7 @@ def renderDomainAsync(namehash: str) -> None: with open(NAMEHASH_CACHE, 'w') as f: json.dump(cache, f) - return rendered + return else: print(f"Error fetching name for hash {namehash}: {name['error']}", flush=True) diff --git a/server.py b/server.py index b49ab0e..396a7a7 100644 --- a/server.py +++ b/server.py @@ -17,8 +17,8 @@ def gunicornServer(): def load_config(self): for key, value in self.options.items(): - if key in self.cfg.settings and value is not None: - self.cfg.set(key.lower(), value) + if key in self.cfg.settings and value is not None: # type: ignore + self.cfg.set(key.lower(), value) # type: ignore def load(self): return self.application