diff --git a/FireWalletBrowser.bsdesign b/FireWalletBrowser.bsdesign index 685900f..b926f57 100644 Binary files a/FireWalletBrowser.bsdesign and b/FireWalletBrowser.bsdesign differ diff --git a/account.py b/account.py index 521294f..9b8b2ea 100644 --- a/account.py +++ b/account.py @@ -126,6 +126,7 @@ def getBalance(account: str): total = info['confirmed'] available = total - info['lockedConfirmed'] + locked = info['lockedConfirmed'] / 1000000 # Convert to HNS total = total / 1000000 @@ -142,7 +143,7 @@ def getBalance(account: str): total = round(total, 2) available = round(available, 2) - return {'available': available, 'total': total} + return {'available': available, 'total': total, 'locked': locked} def getBlockHeight(): # Get the block height @@ -170,14 +171,11 @@ def getPendingTX(account: str): return pending -def getDomains(account): - # Get the domains - # info = hsw.getWalletNames(account) - # if 'error' in info: - # return [] - - # use requests to get the domains - response = requests.get(f"http://x:{APIKEY}@{ip}:12039/wallet/{account}/name?own=true") +def getDomains(account,own=True): + if own: + response = requests.get(f"http://x:{APIKEY}@{ip}:12039/wallet/{account}/name?own=true") + else: + response = requests.get(f"http://x:{APIKEY}@{ip}:12039/wallet/{account}/name") info = response.json() return info @@ -363,8 +361,11 @@ def getNodeSync(): sync = round(sync, 2) return sync +def getBids(account, domain="NONE"): + if domain == "NONE": + return hsw.getWalletBids(account) + -def getBids(account, domain): response = hsw.getWalletBidsByName(domain,account) return response @@ -399,6 +400,35 @@ def revealAuction(account,domain): "error": str(e) } +def revealAll(account): + account_name = check_account(account) + password = ":".join(account.split(":")[1:]) + + if account_name == False: + return { + "error": { + "message": "Invalid account" + } + } + + try: + # Try to select and login to the wallet + response = hsw.rpc_selectWallet(account_name) + if response['error'] is not None: + return + response = hsw.rpc_walletPassphrase(password,10) + if response['error'] is not None: + return + # Try to send the batch of all renew, reveal and redeem actions + + return requests.post(f"http://x:{APIKEY}@{ip}:12039",json={"method": "sendbatch","params": [[["REVEAL"]]]}).json() + except Exception as e: + return { + "error": { + "message": str(e) + } + } + def rescan_auction(account,domain): # Get height of the start of the auction response = hsw.rpc_selectWallet(account) diff --git a/main.py b/main.py index 4e6a6d4..a966e70 100644 --- a/main.py +++ b/main.py @@ -12,6 +12,8 @@ import domainLookup import urllib.parse import importlib import plugin as plugins_module +import gitinfo +import datetime dotenv.load_dotenv() @@ -263,6 +265,119 @@ def check_address(): #endregion #region Domains +@app.route('/auctions') +def auctions(): + # 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") + + balance = account_module.getBalance(account) + locked = balance['locked'] + + # Add commas to the numbers + locked = "{:,}".format(locked) + + + bids = account_module.getBids(account) + domains = account_module.getDomains(account,False) + + # Sort + sort = request.args.get("sort") + if sort == None: + sort = "domain" + sort = sort.lower() + sort_price = "" + sort_price_next = "⬇" + sort_state = "" + sort_state_next = "⬇" + sort_domain = "" + sort_domain_next = "⬇" + reverse = False + + direction = request.args.get("direction") + if direction == None: + direction = "⬇" + + if direction == "⬆": + reverse = True + + if sort == "price": + # Sort by price + bids = sorted(bids, key=lambda k: k['value'],reverse=reverse) + sort_price = direction + sort_price_next = reverseDirection(direction) + elif sort == "state": + sort_state = direction + sort_state_next = reverseDirection(direction) + domains = sorted(domains, key=lambda k: k['state'],reverse=reverse) + else: + # Sort by domain + bids = sorted(bids, key=lambda k: k['name'],reverse=reverse) + sort_domain = direction + sort_domain_next = reverseDirection(direction) + + if sort == "state": + bidsHtml = render.bidDomains(bids,domains,True) + else: + bidsHtml = render.bidDomains(bids,domains) + + + pending_reveals = 0 + for domain in domains: + if domain['state'] == "REVEAL": + for bid in bids: + if bid['name'] == domain['name']: + bid_found = False + reveals = account_module.getReveals(account,domain['name']) + for reveal in reveals: + if reveal['own'] == True: + if bid['value'] == reveal['value']: + bid_found = True + if not bid_found: + pending_reveals += 1 + + plugins = "" + # dashFunctions = plugins_module.getDashboardFunctions() + # for function in dashFunctions: + # functionOutput = plugins_module.runPluginFunction(function["plugin"],function["function"],{},request.cookies.get("account")) + # plugins += render.plugin_output_dash(functionOutput,plugins_module.getPluginFunctionReturns(function["plugin"],function["function"])) + + message = '' + if 'message' in request.args: + message = request.args.get("message") + return render_template("auctions.html", account=account, locked=locked, domains=bidsHtml, + domainsMobile=bidsHtml, plugins=plugins, + domain_count=bidsHtml, sync=account_module.getNodeSync(), + sort_price=sort_price,sort_state=sort_state, + sort_domain=sort_domain,sort_price_next=sort_price_next, + sort_state_next=sort_state_next,sort_domain_next=sort_domain_next, + bids=len(bids),reveal=pending_reveals,message=message) + +@app.route('/reveal') +def revealAllBids(): + # 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") + + response = account_module.revealAll(request.cookies.get("account")) + if 'error' in response: + print(response) + if response['error'] != None: + if response['error']['message'] == "Nothing to do.": + return redirect("/auctions?message=No reveals pending") + return redirect("/auctions?message=" + response['error']['message']) + + return redirect("/success?tx=" + response['hash']) + + @app.route('/search') def search(): # Check if the user is logged in @@ -928,8 +1043,17 @@ def settings(): if success == None: success = "" + info = gitinfo.get_git_info() + branch = info['refs'] + if branch == "main": + branch = "" + last_commit = info['author_date'] + # import to time from format "2024-02-13 11:24:03" + last_commit = datetime.datetime.strptime(last_commit, "%Y-%m-%d %H:%M:%S") + version = f'{last_commit.strftime("%y-%m-%d")} ({branch})' + return render_template("settings.html", account=account,sync=account_module.getNodeSync(), - error=error,success=success) + error=error,success=success,version=version) @app.route('/settings/') def settings_action(action): diff --git a/plugins/automations.py b/plugins/automations.py index 38f8e50..e601ffa 100644 --- a/plugins/automations.py +++ b/plugins/automations.py @@ -74,10 +74,8 @@ def automations_background(authentication): if response['error'] is not None: return # Try to send the batch of all renew, reveal and redeem actions - response = requests.post(f"http://x:{APIKEY}@{ip}:12039",json={ - "method": "sendbatch", - "params": [[["RENEW"], ["REVEAL"], ["REDEEM"]]] - }).json() - print(response) + requests.post(f"http://x:{APIKEY}@{ip}:12039",json={"method": "sendbatch","params": [[["RENEW"]]]}) + requests.post(f"http://x:{APIKEY}@{ip}:12039",json={"method": "sendbatch","params": [[["REVEAL"]]]}) + requests.post(f"http://x:{APIKEY}@{ip}:12039",json={"method": "sendbatch","params": [[["REDEEM"]]]}) except Exception as e: print(e) \ No newline at end of file diff --git a/render.py b/render.py index aa00b46..eb35f5c 100644 --- a/render.py +++ b/render.py @@ -13,6 +13,8 @@ def domains(domains, mobile=False): expires = domain['stats'] if 'daysUntilExpire' in expires: expires = expires['daysUntilExpire'] + else: + expires = "No expiration date" paid = domain['value'] paid = paid / 1000000 @@ -172,6 +174,51 @@ def bids(bids,reveals): return html +def bidDomains(bids,domains, sortState=False): + html = '' + if not sortState: + for bid in bids: + for domain in domains: + if bid['name'] == domain['name']: + lockup = bid['lockup'] + lockup = lockup / 1000000 + lockup = round(lockup, 2) + bidValue = bid['value'] / 1000000 + bidValue = round(bidValue, 2) + blind = lockup - bidValue + bidValue = "{:,}".format(bidValue) + blind = "{:,}".format(blind) + + bidDisplay = f'{bidValue} HNS + {blind} HNS blind' + + + html += "" + html += f"{domain['name']}" + html += f"{domain['state']}" + html += f"{bidDisplay}" + html += "" + else: + for domain in domains: + for bid in bids: + if bid['name'] == domain['name']: + lockup = bid['lockup'] + lockup = lockup / 1000000 + lockup = round(lockup, 2) + bidValue = bid['value'] / 1000000 + bidValue = round(bidValue, 2) + blind = lockup - bidValue + bidValue = "{:,}".format(bidValue) + blind = "{:,}".format(blind) + + bidDisplay = f'{bidValue} HNS + {blind} HNS blind' + html += "" + html += f"{domain['name']}" + html += f"{domain['state']}" + html += f"{bidDisplay}" + html += "" + return html + + def wallets(wallets): html = '' for wallet in wallets: diff --git a/requirements.txt b/requirements.txt index 6f73b4e..ef58b6f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,5 @@ dnspython cryptography requests-doh Flask-QRcode -PySocks \ No newline at end of file +PySocks +python-git-info \ No newline at end of file diff --git a/templates/404.html b/templates/404.html index c5c0fbb..d2ea3cc 100644 --- a/templates/404.html +++ b/templates/404.html @@ -13,7 +13,9 @@ + + @@ -28,6 +30,7 @@