Merge pull request 'Update Auctions page to include more info and be easier to read' (#1) from dev into main
All checks were successful
Build Docker / Build Image (push) Successful in 1m10s
All checks were successful
Build Docker / Build Image (push) Successful in 1m10s
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
Binary file not shown.
88
account.py
88
account.py
@@ -109,8 +109,7 @@ def createWallet(account: str, password: str):
|
|||||||
}
|
}
|
||||||
# Create the account
|
# Create the account
|
||||||
# Python wrapper doesn't support this yet
|
# Python wrapper doesn't support this yet
|
||||||
response = requests.put(
|
response = requests.put(get_wallet_api_url(f"wallet/{account}"))
|
||||||
f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}")
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
return {
|
return {
|
||||||
"error": {
|
"error": {
|
||||||
@@ -123,7 +122,7 @@ def createWallet(account: str, password: str):
|
|||||||
seed = seed['mnemonic']['phrase']
|
seed = seed['mnemonic']['phrase']
|
||||||
|
|
||||||
# Encrypt the wallet (python wrapper doesn't support this yet)
|
# Encrypt the wallet (python wrapper doesn't support this yet)
|
||||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/passphrase",
|
response = requests.post(get_wallet_api_url(f"/wallet/{account}/passphrase"),
|
||||||
json={"passphrase": password})
|
json={"passphrase": password})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -147,8 +146,7 @@ def importWallet(account: str, password: str, seed: str):
|
|||||||
"mnemonic": seed,
|
"mnemonic": seed,
|
||||||
}
|
}
|
||||||
|
|
||||||
response = requests.put(
|
response = requests.put(get_wallet_api_url(f"/wallet/{account}"), json=data)
|
||||||
f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}", json=data)
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
return {
|
return {
|
||||||
"error": {
|
"error": {
|
||||||
@@ -186,7 +184,6 @@ def selectWallet(account: str):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def getBalance(account: str):
|
def getBalance(account: str):
|
||||||
# Get the total balance
|
# Get the total balance
|
||||||
info = hsw.getBalance('default', account)
|
info = hsw.getBalance('default', account)
|
||||||
@@ -251,11 +248,9 @@ def getPendingTX(account: str):
|
|||||||
|
|
||||||
def getDomains(account, own=True):
|
def getDomains(account, own=True):
|
||||||
if own:
|
if own:
|
||||||
response = requests.get(
|
response = requests.get(get_wallet_api_url(f"/wallet/{account}/name?own=true"))
|
||||||
f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/name?own=true")
|
|
||||||
else:
|
else:
|
||||||
response = requests.get(
|
response = requests.get(get_wallet_api_url(f"/wallet/{account}/name"))
|
||||||
f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/name")
|
|
||||||
info = response.json()
|
info = response.json()
|
||||||
|
|
||||||
if SHOW_EXPIRED:
|
if SHOW_EXPIRED:
|
||||||
@@ -339,11 +334,9 @@ def getTransactions(account, page=1, limit=100):
|
|||||||
lastTX = getTXFromPage(account, page-1, limit)
|
lastTX = getTXFromPage(account, page-1, limit)
|
||||||
|
|
||||||
if lastTX:
|
if lastTX:
|
||||||
response = requests.get(
|
response = requests.get(get_wallet_api_url(f"/wallet/{account}/tx/history?reverse=true&limit={limit}&after={lastTX}"))
|
||||||
f'http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/tx/history?reverse=true&limit={limit}&after={lastTX}')
|
|
||||||
elif page == 1:
|
elif page == 1:
|
||||||
response = requests.get(
|
response = requests.get(get_wallet_api_url(f"/wallet/{account}/tx/history?reverse=true&limit={limit}"))
|
||||||
f'http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/tx/history?reverse=true&limit={limit}')
|
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@@ -383,7 +376,7 @@ def check_address(address: str, allow_name: bool = True, return_address: bool =
|
|||||||
return check_hip2(address[1:])
|
return check_hip2(address[1:])
|
||||||
|
|
||||||
# Check if the address is a valid HNS address
|
# Check if the address is a valid HNS address
|
||||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_NODE_PORT}", json={
|
response = requests.post(get_node_api_url(), json={
|
||||||
"method": "validateaddress",
|
"method": "validateaddress",
|
||||||
"params": [address]
|
"params": [address]
|
||||||
}).json()
|
}).json()
|
||||||
@@ -431,8 +424,6 @@ def send(account, address, amount):
|
|||||||
|
|
||||||
response = hsw.rpc_walletPassphrase(password, 10)
|
response = hsw.rpc_walletPassphrase(password, 10)
|
||||||
# Unlock the account
|
# Unlock the account
|
||||||
# response = requests.post(f"http://x:{APIKEY}@{ip}:{HSD_WALLET_PORT}/wallet/{account_name}/unlock",
|
|
||||||
# json={"passphrase": password,"timeout": 10})
|
|
||||||
if response['error'] is not None:
|
if response['error'] is not None:
|
||||||
if response['error']['message'] != "Wallet is not encrypted.":
|
if response['error']['message'] != "Wallet is not encrypted.":
|
||||||
return {
|
return {
|
||||||
@@ -454,9 +445,18 @@ def send(account, address, amount):
|
|||||||
|
|
||||||
|
|
||||||
def isOwnDomain(account, name: str):
|
def isOwnDomain(account, name: str):
|
||||||
domains = getDomains(account)
|
# Get domain
|
||||||
for domain in domains:
|
domain_info = getDomain(name)
|
||||||
if domain['name'] == name:
|
owner = getAddressFromCoin(domain_info['info']['owner']['hash'],domain_info['info']['owner']['index'])
|
||||||
|
# Select the account
|
||||||
|
hsw.rpc_selectWallet(account)
|
||||||
|
account = hsw.rpc_getAccount(owner)
|
||||||
|
|
||||||
|
if 'error' in account and account['error'] is not None:
|
||||||
|
return False
|
||||||
|
if 'result' not in account:
|
||||||
|
return False
|
||||||
|
if account['result'] == 'default':
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -474,20 +474,14 @@ def getDomain(domain: str):
|
|||||||
|
|
||||||
def getAddressFromCoin(coinhash: str, coinindex = 0):
|
def getAddressFromCoin(coinhash: str, coinindex = 0):
|
||||||
# Get the address from the hash
|
# Get the address from the hash
|
||||||
response = requests.get(f"http://x:{HSD_API}@{HSD_IP}:{HSD_NODE_PORT}/coin/{coinhash}/{coinindex}")
|
response = requests.get(get_node_api_url(f"coin/{coinhash}/{coinindex}"))
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
return {
|
print(f"Error getting address from coin: {response.text}")
|
||||||
"error": {
|
return "No Owner"
|
||||||
"message": "Error getting address from coin"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data = response.json()
|
data = response.json()
|
||||||
if 'address' not in data:
|
if 'address' not in data:
|
||||||
return {
|
print(json.dumps(data, indent=4))
|
||||||
"error": {
|
return "No Owner"
|
||||||
"message": "Error getting address from coin"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data['address']
|
return data['address']
|
||||||
|
|
||||||
|
|
||||||
@@ -783,7 +777,7 @@ def revealAll(account):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}", json={"method": "sendbatch", "params": [[["REVEAL"]]]}).json()
|
return requests.post(get_wallet_api_url(), json={"method": "sendbatch", "params": [[["REVEAL"]]]}).json()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {
|
return {
|
||||||
"error": {
|
"error": {
|
||||||
@@ -817,7 +811,7 @@ def redeemAll(account):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}", json={"method": "sendbatch", "params": [[["REDEEM"]]]}).json()
|
return requests.post(get_wallet_api_url(), json={"method": "sendbatch", "params": [[["REDEEM"]]]}).json()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {
|
return {
|
||||||
"error": {
|
"error": {
|
||||||
@@ -1089,7 +1083,7 @@ def sendBatch(account, batch):
|
|||||||
"message": response['error']['message']
|
"message": response['error']['message']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}", json={
|
response = requests.post(get_wallet_api_url(), json={
|
||||||
"method": "sendbatch",
|
"method": "sendbatch",
|
||||||
"params": [batch]
|
"params": [batch]
|
||||||
}).json()
|
}).json()
|
||||||
@@ -1138,7 +1132,7 @@ def createBatch(account, batch):
|
|||||||
"message": response['error']['message']
|
"message": response['error']['message']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}", json={
|
response = requests.post(get_wallet_api_url(), json={
|
||||||
"method": "createbatch",
|
"method": "createbatch",
|
||||||
"params": [batch]
|
"params": [batch]
|
||||||
}).json()
|
}).json()
|
||||||
@@ -1198,7 +1192,7 @@ def zapTXs(account):
|
|||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account_name}/zap",
|
response = requests.post(get_wallet_api_url(f"/wallet/{account_name}/zap"),
|
||||||
json={"age": age,
|
json={"age": age,
|
||||||
"account": "default"
|
"account": "default"
|
||||||
})
|
})
|
||||||
@@ -1327,3 +1321,25 @@ def generateReport(account, format="{name},{expiry},{value},{maxBid}"):
|
|||||||
|
|
||||||
def convertHNS(value: int):
|
def convertHNS(value: int):
|
||||||
return value/1000000
|
return value/1000000
|
||||||
|
return value/1000000
|
||||||
|
|
||||||
|
|
||||||
|
def get_node_api_url(path=''):
|
||||||
|
"""Construct a URL for the HSD node API."""
|
||||||
|
base_url = f"http://x:{HSD_API}@{HSD_IP}:{HSD_NODE_PORT}"
|
||||||
|
if path:
|
||||||
|
# Ensure path starts with a slash if it's not empty
|
||||||
|
if not path.startswith('/'):
|
||||||
|
path = f'/{path}'
|
||||||
|
return f"{base_url}{path}"
|
||||||
|
return base_url
|
||||||
|
|
||||||
|
def get_wallet_api_url(path=''):
|
||||||
|
"""Construct a URL for the HSD wallet API."""
|
||||||
|
base_url = f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}"
|
||||||
|
if path:
|
||||||
|
# Ensure path starts with a slash if it's not empty
|
||||||
|
if not path.startswith('/'):
|
||||||
|
path = f'/{path}'
|
||||||
|
return f"{base_url}{path}"
|
||||||
|
return base_url
|
||||||
|
|||||||
61
main.py
61
main.py
@@ -32,6 +32,30 @@ revokeCheck = random.randint(100000,999999)
|
|||||||
|
|
||||||
THEME = os.getenv("THEME")
|
THEME = os.getenv("THEME")
|
||||||
|
|
||||||
|
|
||||||
|
def blocks_to_time(blocks: int) -> str:
|
||||||
|
"""
|
||||||
|
Convert blocks to time in a human-readable format.
|
||||||
|
Blocks are mined approximately every 10 minutes.
|
||||||
|
"""
|
||||||
|
if blocks < 0:
|
||||||
|
return "Invalid time"
|
||||||
|
|
||||||
|
if blocks < 6:
|
||||||
|
return f"{blocks * 10} mins"
|
||||||
|
elif blocks < 144:
|
||||||
|
hours = blocks // 6
|
||||||
|
minutes = (blocks % 6) * 10
|
||||||
|
return f"{hours} hrs {minutes} mins"
|
||||||
|
else:
|
||||||
|
days = blocks // 144
|
||||||
|
hours = (blocks % 144) // 6
|
||||||
|
return f"{days} days {hours} hrs"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
# Check if the user is logged in
|
# Check if the user is logged in
|
||||||
@@ -445,10 +469,11 @@ def search():
|
|||||||
state="AVAILABLE", next="Available Now",plugins=plugins)
|
state="AVAILABLE", next="Available Now",plugins=plugins)
|
||||||
|
|
||||||
state = domain['info']['state']
|
state = domain['info']['state']
|
||||||
|
stats = domain['info']['stats']
|
||||||
if state == 'CLOSED':
|
if state == 'CLOSED':
|
||||||
if domain['info']['registered']:
|
if domain['info']['registered']:
|
||||||
state = 'REGISTERED'
|
state = 'REGISTERED'
|
||||||
expires = domain['info']['stats']['daysUntilExpire']
|
expires = stats['daysUntilExpire']
|
||||||
next = f"Expires in ~{expires} days"
|
next = f"Expires in ~{expires} days"
|
||||||
else:
|
else:
|
||||||
state = 'AVAILABLE'
|
state = 'AVAILABLE'
|
||||||
@@ -456,11 +481,11 @@ def search():
|
|||||||
elif state == "REVOKED":
|
elif state == "REVOKED":
|
||||||
next = "Available Now"
|
next = "Available Now"
|
||||||
elif state == 'OPENING':
|
elif state == 'OPENING':
|
||||||
next = "Bidding opens in ~" + str(domain['info']['stats']['blocksUntilBidding']) + " blocks"
|
next = f"Bidding opens in {str(stats['blocksUntilBidding'])} blocks (~{blocks_to_time(stats['blocksUntilBidding'])})"
|
||||||
elif state == 'BIDDING':
|
elif state == 'BIDDING':
|
||||||
next = "Reveal in ~" + str(domain['info']['stats']['blocksUntilReveal']) + " blocks"
|
next = f"Reveal in {str(stats['blocksUntilReveal'])} blocks (~{blocks_to_time(stats['blocksUntilReveal'])})"
|
||||||
elif state == 'REVEAL':
|
elif state == 'REVEAL':
|
||||||
next = "Reveal ends in ~" + str(domain['info']['stats']['blocksUntilClose']) + " blocks"
|
next = f"Reveal ends in {str(stats['blocksUntilClose'])} blocks (~{blocks_to_time(stats['blocksUntilClose'])})"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -502,10 +527,7 @@ def manage(domain: str):
|
|||||||
|
|
||||||
domain = domain.lower()
|
domain = domain.lower()
|
||||||
|
|
||||||
own_domains = account_module.getDomains(account)
|
if not account_module.isOwnDomain(account, domain):
|
||||||
own_domains = [x['name'] for x in own_domains]
|
|
||||||
own_domains = [x.lower() for x in own_domains]
|
|
||||||
if domain not in own_domains:
|
|
||||||
return redirect("/search?q=" + domain)
|
return redirect("/search?q=" + domain)
|
||||||
|
|
||||||
domain_info = account_module.getDomain(domain)
|
domain_info = account_module.getDomain(domain)
|
||||||
@@ -514,7 +536,10 @@ def manage(domain: str):
|
|||||||
rendered=renderDomain(domain),
|
rendered=renderDomain(domain),
|
||||||
domain=domain, error=domain_info['error'])
|
domain=domain, error=domain_info['error'])
|
||||||
|
|
||||||
|
if domain_info['info'] is not None and 'stats' in domain_info['info'] and 'daysUntilExpire' in domain_info['info']['stats']:
|
||||||
expiry = domain_info['info']['stats']['daysUntilExpire']
|
expiry = domain_info['info']['stats']['daysUntilExpire']
|
||||||
|
else:
|
||||||
|
expiry = "Unknown"
|
||||||
dns = account_module.getDNS(domain)
|
dns = account_module.getDNS(domain)
|
||||||
raw_dns = str(dns).replace("'",'"')
|
raw_dns = str(dns).replace("'",'"')
|
||||||
dns = render.dns(dns)
|
dns = render.dns(dns)
|
||||||
@@ -900,7 +925,7 @@ def auction(domain):
|
|||||||
reveal['bid'] = revealInfo
|
reveal['bid'] = revealInfo
|
||||||
bids = render.bids(bids,reveals)
|
bids = render.bids(bids,reveals)
|
||||||
|
|
||||||
|
stats = domainInfo['info']['stats'] if 'stats' in domainInfo['info'] else {}
|
||||||
if state == 'CLOSED':
|
if state == 'CLOSED':
|
||||||
if not domainInfo['info']['registered']:
|
if not domainInfo['info']['registered']:
|
||||||
if account_module.isOwnDomain(account,domain):
|
if account_module.isOwnDomain(account,domain):
|
||||||
@@ -928,11 +953,21 @@ def auction(domain):
|
|||||||
next = "Available Now"
|
next = "Available Now"
|
||||||
next_action = f'<a href="/auction/{domain}/open">Open Auction</a>'
|
next_action = f'<a href="/auction/{domain}/open">Open Auction</a>'
|
||||||
elif state == 'OPENING':
|
elif state == 'OPENING':
|
||||||
next = "Bidding opens in ~" + str(domainInfo['info']['stats']['blocksUntilBidding']) + " blocks"
|
next = f"Bidding opens in {str(stats['blocksUntilBidding'])} blocks (~{blocks_to_time(stats['blocksUntilBidding'])})"
|
||||||
elif state == 'BIDDING':
|
elif state == 'BIDDING':
|
||||||
next = "Reveal in ~" + str(domainInfo['info']['stats']['blocksUntilReveal']) + " blocks"
|
next = f"Reveal in {stats['blocksUntilReveal']} blocks (~{blocks_to_time(stats['blocksUntilReveal'])})"
|
||||||
|
if stats['blocksUntilReveal'] == 1:
|
||||||
|
next += "<br>Bidding no longer possible"
|
||||||
|
elif stats['blocksUntilReveal'] == 2:
|
||||||
|
next += "<br>LAST CHANCE TO BID"
|
||||||
|
elif stats['blocksUntilReveal'] == 3:
|
||||||
|
next += f"<br>Next block is last chance to bid"
|
||||||
|
elif stats['blocksUntilReveal'] < 6:
|
||||||
|
next += f"<br>Last chance to bid in {stats['blocksUntilReveal']-2} blocks"
|
||||||
|
|
||||||
|
|
||||||
elif state == 'REVEAL':
|
elif state == 'REVEAL':
|
||||||
next = "Reveal ends in ~" + str(domainInfo['info']['stats']['blocksUntilClose']) + " blocks"
|
next = f"Reveal ends in {str(stats['blocksUntilClose'])} blocks (~{blocks_to_time(stats['blocksUntilClose'])})"
|
||||||
next_action = f'<a href="/auction/{domain}/reveal">Reveal All</a>'
|
next_action = f'<a href="/auction/{domain}/reveal">Reveal All</a>'
|
||||||
|
|
||||||
message = ''
|
message = ''
|
||||||
@@ -1070,7 +1105,7 @@ def reveal_auction(domain):
|
|||||||
return redirect("/logout")
|
return redirect("/logout")
|
||||||
|
|
||||||
domain = domain.lower()
|
domain = domain.lower()
|
||||||
response = account_module(request.cookies.get("account"),domain)
|
response = account_module.revealAuction(request.cookies.get("account"),domain)
|
||||||
if 'error' in response:
|
if 'error' in response:
|
||||||
return redirect("/auction/" + domain + "?message=" + response['error']['message'])
|
return redirect("/auction/" + domain + "?message=" + response['error']['message'])
|
||||||
return redirect("/success?tx=" + response['hash'])
|
return redirect("/success?tx=" + response['hash'])
|
||||||
|
|||||||
56
render.py
56
render.py
@@ -210,7 +210,6 @@ def dns(data, edit=False):
|
|||||||
html_output = ""
|
html_output = ""
|
||||||
index = 0
|
index = 0
|
||||||
for entry in data:
|
for entry in data:
|
||||||
print(entry, flush=True)
|
|
||||||
html_output += f"<tr><td>{entry['type']}</td>\n"
|
html_output += f"<tr><td>{entry['type']}</td>\n"
|
||||||
|
|
||||||
if entry['type'] != 'DS' and not entry['type'].startswith("GLUE") and not entry['type'].startswith("SYNTH"):
|
if entry['type'] != 'DS' and not entry['type'].startswith("GLUE") and not entry['type'].startswith("SYNTH"):
|
||||||
@@ -279,30 +278,61 @@ def timestamp_to_readable_time(timestamp):
|
|||||||
return readable_time
|
return readable_time
|
||||||
|
|
||||||
def bids(bids,reveals):
|
def bids(bids,reveals):
|
||||||
html = ''
|
# Create a list to hold bid data for sorting
|
||||||
|
bid_data = []
|
||||||
|
|
||||||
|
# Prepare data for sorting
|
||||||
for bid in bids:
|
for bid in bids:
|
||||||
lockup = bid['lockup']
|
lockup = bid['lockup'] / 1000000
|
||||||
lockup = lockup / 1000000
|
|
||||||
html += "<tr>"
|
|
||||||
html += f"<td>{lockup:,.2f} HNS</td>"
|
|
||||||
revealed = False
|
revealed = False
|
||||||
|
value = 0
|
||||||
|
|
||||||
|
# Check if this bid has been revealed
|
||||||
for reveal in reveals:
|
for reveal in reveals:
|
||||||
if reveal['bid'] == bid['prevout']['hash']:
|
if reveal['bid'] == bid['prevout']['hash']:
|
||||||
revealed = True
|
revealed = True
|
||||||
value = reveal['value']
|
value = reveal['value'] / 1000000
|
||||||
value = value / 1000000
|
|
||||||
html += f"<td>{value:,.2f} HNS</td>"
|
|
||||||
bidValue = lockup - value
|
|
||||||
html += f"<td>{bidValue:,.2f} HNS</td>"
|
|
||||||
break
|
break
|
||||||
if not revealed:
|
|
||||||
|
# Store all relevant information for sorting and display
|
||||||
|
bid_data.append({
|
||||||
|
'bid': bid,
|
||||||
|
'lockup': lockup,
|
||||||
|
'revealed': revealed,
|
||||||
|
'value': value,
|
||||||
|
'sort_value': value if revealed else lockup # Use value for sorting if revealed, otherwise lockup
|
||||||
|
})
|
||||||
|
|
||||||
|
# Sort by the sort_value in descending order (highest first)
|
||||||
|
bid_data.sort(key=lambda x: x['sort_value'], reverse=True)
|
||||||
|
|
||||||
|
# Generate HTML from sorted data
|
||||||
|
html = ''
|
||||||
|
for data in bid_data:
|
||||||
|
bid = data['bid']
|
||||||
|
lockup = data['lockup']
|
||||||
|
revealed = data['revealed']
|
||||||
|
value = data['value']
|
||||||
|
|
||||||
|
html += "<tr>"
|
||||||
|
html += f"<td>{lockup:,.2f} HNS</td>"
|
||||||
|
|
||||||
|
if revealed:
|
||||||
|
bidValue = lockup - value
|
||||||
|
html += f"<td>{value:,.2f} HNS</td>"
|
||||||
|
html += f"<td>{bidValue:,.2f} HNS</td>"
|
||||||
|
else:
|
||||||
html += f"<td>Hidden until reveal</td>"
|
html += f"<td>Hidden until reveal</td>"
|
||||||
html += f"<td>Hidden until reveal</td>"
|
html += f"<td>Hidden until reveal</td>"
|
||||||
|
|
||||||
if bid['own']:
|
if bid['own']:
|
||||||
html += "<td>You</td>"
|
html += "<td>You</td>"
|
||||||
else:
|
else:
|
||||||
html += "<td>Unknown</td>"
|
html += f"<td>Unknown</td>"
|
||||||
|
|
||||||
|
html += f"<td><a class='text-decoration-none' style='color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));' href='{TX_EXPLORER_URL}{bid['prevout']['hash']}'>Bid TX 🔗</a></td>"
|
||||||
html += "</tr>"
|
html += "</tr>"
|
||||||
|
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="stick-right">{{next_action|safe}}</div>
|
<div class="stick-right">{{next_action|safe}}</div>
|
||||||
<h4 class="card-title">{{rendered}}</h4>
|
<h4 class="card-title">{{rendered}}</h4>
|
||||||
<h6 class="text-muted mb-2 card-subtitle">{{next}}</h6>
|
<h6 class="text-muted mb-2 card-subtitle">{{next | safe}}</h6>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -93,6 +93,7 @@
|
|||||||
<th>Bid</th>
|
<th>Bid</th>
|
||||||
<th>Blind</th>
|
<th>Blind</th>
|
||||||
<th>Owner</th>
|
<th>Owner</th>
|
||||||
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user