Compare commits
1 Commits
feat/aucti
...
feat/insta
| Author | SHA1 | Date | |
|---|---|---|---|
|
0fc95d0eb1
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -14,5 +14,5 @@ plugins/signatures.json
|
||||
user_data/
|
||||
customPlugins/
|
||||
cache/
|
||||
build/
|
||||
dist/
|
||||
build/
|
||||
@@ -10,7 +10,7 @@ COPY . /app
|
||||
|
||||
# Add mount point for data volume
|
||||
# VOLUME /data
|
||||
RUN apk add git openssl curl
|
||||
RUN apk add git openssl
|
||||
|
||||
ENTRYPOINT ["python3"]
|
||||
CMD ["server.py"]
|
||||
|
||||
Binary file not shown.
@@ -122,7 +122,7 @@ HSD_IP: HSD IP address
|
||||
THEME: Theme to use (dark-purple, black)
|
||||
SHOW_EXPIRED: Show expired domains (true/false)
|
||||
EXCLUDE: Comma separated list of wallets to exclude from the wallet list (default primary)
|
||||
EXPLORER_TX: URL for exploring transactions (default https://shakeshift.com/transaction/)
|
||||
EXPLORER_TX: URL for exploring transactions (default https://niami.io/tx/)
|
||||
HSD_NETWORK: Network to connect to (main, regtest, simnet)
|
||||
```
|
||||
|
||||
|
||||
538
account.py
538
account.py
@@ -7,7 +7,6 @@ import re
|
||||
import domainLookup
|
||||
import json
|
||||
import time
|
||||
import concurrent.futures
|
||||
|
||||
dotenv.load_dotenv()
|
||||
|
||||
@@ -52,13 +51,11 @@ EXCLUDE = ["primary"]
|
||||
if os.getenv("EXCLUDE") is not None:
|
||||
EXCLUDE = os.getenv("EXCLUDE").split(",")
|
||||
|
||||
|
||||
def hsdConnected():
|
||||
if hsdVersion() == -1:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def hsdVersion(format=True):
|
||||
info = hsd.getInfo()
|
||||
if 'error' in info:
|
||||
@@ -68,7 +65,6 @@ def hsdVersion(format=True):
|
||||
else:
|
||||
return info['version']
|
||||
|
||||
|
||||
def check_account(cookie: str):
|
||||
if cookie is None:
|
||||
return False
|
||||
@@ -84,7 +80,6 @@ def check_account(cookie: str):
|
||||
return False
|
||||
return account
|
||||
|
||||
|
||||
def check_password(cookie: str, password: str):
|
||||
account = check_account(cookie)
|
||||
if account == False:
|
||||
@@ -100,7 +95,6 @@ def check_password(cookie: str, password: str):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def createWallet(account: str, password: str):
|
||||
if not hsdConnected():
|
||||
return {
|
||||
@@ -110,7 +104,7 @@ def createWallet(account: str, password: str):
|
||||
}
|
||||
# Create the account
|
||||
# Python wrapper doesn't support this yet
|
||||
response = requests.put(get_wallet_api_url(f"wallet/{account}"))
|
||||
response = requests.put(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}")
|
||||
if response.status_code != 200:
|
||||
return {
|
||||
"error": {
|
||||
@@ -122,8 +116,9 @@ def createWallet(account: str, password: str):
|
||||
seed = hsw.getMasterHDKey(account)
|
||||
seed = seed['mnemonic']['phrase']
|
||||
|
||||
|
||||
# Encrypt the wallet (python wrapper doesn't support this yet)
|
||||
response = requests.post(get_wallet_api_url(f"/wallet/{account}/passphrase"),
|
||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/passphrase",
|
||||
json={"passphrase": password})
|
||||
|
||||
return {
|
||||
@@ -132,7 +127,6 @@ def createWallet(account: str, password: str):
|
||||
"password": password
|
||||
}
|
||||
|
||||
|
||||
def importWallet(account: str, password: str,seed: str):
|
||||
if not hsdConnected():
|
||||
return {
|
||||
@@ -147,7 +141,7 @@ def importWallet(account: str, password: str, seed: str):
|
||||
"mnemonic": seed,
|
||||
}
|
||||
|
||||
response = requests.put(get_wallet_api_url(f"/wallet/{account}"), json=data)
|
||||
response = requests.put(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}",json=data)
|
||||
if response.status_code != 200:
|
||||
return {
|
||||
"error": {
|
||||
@@ -174,7 +168,6 @@ def listWallets():
|
||||
return response
|
||||
return ['Wallet not connected']
|
||||
|
||||
|
||||
def selectWallet(account: str):
|
||||
# Select wallet
|
||||
response = hsw.rpc_selectWallet(account)
|
||||
@@ -207,13 +200,13 @@ def getBalance(account: str):
|
||||
total = total - (domainValue/1000000)
|
||||
locked = locked - (domainValue/1000000)
|
||||
|
||||
|
||||
# Only keep 2 decimal places
|
||||
total = round(total, 2)
|
||||
available = round(available, 2)
|
||||
|
||||
return {'available': available, 'total': total, 'locked': locked}
|
||||
|
||||
|
||||
def getBlockHeight():
|
||||
# Get the block height
|
||||
info = hsd.getInfo()
|
||||
@@ -221,7 +214,6 @@ def getBlockHeight():
|
||||
return 0
|
||||
return info['chain']['height']
|
||||
|
||||
|
||||
def getAddress(account: str):
|
||||
# Get the address
|
||||
info = hsw.getAccountInfo(account, 'default')
|
||||
@@ -229,7 +221,6 @@ def getAddress(account: str):
|
||||
return ''
|
||||
return info['receiveAddress']
|
||||
|
||||
|
||||
def getPendingTX(account: str):
|
||||
pending = 0
|
||||
page = 1
|
||||
@@ -246,12 +237,11 @@ def getPendingTX(account: str):
|
||||
break
|
||||
return pending
|
||||
|
||||
|
||||
def getDomains(account,own=True):
|
||||
if own:
|
||||
response = requests.get(get_wallet_api_url(f"/wallet/{account}/name?own=true"))
|
||||
response = requests.get(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/name?own=true")
|
||||
else:
|
||||
response = requests.get(get_wallet_api_url(f"/wallet/{account}/name"))
|
||||
response = requests.get(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/name")
|
||||
info = response.json()
|
||||
|
||||
if SHOW_EXPIRED:
|
||||
@@ -266,8 +256,8 @@ def getDomains(account, own=True):
|
||||
continue
|
||||
domains.append(domain)
|
||||
|
||||
return domains
|
||||
|
||||
return domains
|
||||
|
||||
def getPageTXCache(account,page,size=100):
|
||||
page = f"{page}-{size}"
|
||||
@@ -284,7 +274,6 @@ def getPageTXCache(account, page, size=100):
|
||||
return pageCache[page]['txid']
|
||||
return None
|
||||
|
||||
|
||||
def pushPageTXCache(account,page,txid,size=100):
|
||||
page = f"{page}-{size}"
|
||||
if not os.path.exists(f'cache/{account}_page.json'):
|
||||
@@ -302,7 +291,6 @@ def pushPageTXCache(account, page, txid, size=100):
|
||||
|
||||
return pageCache[page]['txid']
|
||||
|
||||
|
||||
def getTXFromPage(account,page,size=100):
|
||||
if page == 1:
|
||||
return getTransactions(account,1,size)[-1]['hash']
|
||||
@@ -318,6 +306,7 @@ def getTXFromPage(account, page, size=100):
|
||||
return hash
|
||||
|
||||
|
||||
|
||||
def getTransactions(account,page=1,limit=100):
|
||||
# Get the transactions
|
||||
if hsdVersion() < 7:
|
||||
@@ -335,9 +324,9 @@ def getTransactions(account, page=1, limit=100):
|
||||
lastTX = getTXFromPage(account,page-1,limit)
|
||||
|
||||
if lastTX:
|
||||
response = requests.get(get_wallet_api_url(f"/wallet/{account}/tx/history?reverse=true&limit={limit}&after={lastTX}"))
|
||||
response = requests.get(f'http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/tx/history?reverse=true&limit={limit}&after={lastTX}')
|
||||
elif page == 1:
|
||||
response = requests.get(get_wallet_api_url(f"/wallet/{account}/tx/history?reverse=true&limit={limit}"))
|
||||
response = requests.get(f'http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account}/tx/history?reverse=true&limit={limit}')
|
||||
else:
|
||||
return []
|
||||
|
||||
@@ -353,7 +342,6 @@ def getTransactions(account, page=1, limit=100):
|
||||
pushPageTXCache(account,page,data[-1]['hash'],limit)
|
||||
return data
|
||||
|
||||
|
||||
def getAllTransactions(account):
|
||||
# Get the transactions
|
||||
page = 0
|
||||
@@ -365,7 +353,6 @@ def getAllTransactions(account):
|
||||
page += 1
|
||||
return txs
|
||||
|
||||
|
||||
def check_address(address: str, allow_name: bool = True, return_address: bool = False):
|
||||
# Check if the address is valid
|
||||
if address.startswith('@'):
|
||||
@@ -377,7 +364,7 @@ def check_address(address: str, allow_name: bool = True, return_address: bool =
|
||||
return check_hip2(address[1:])
|
||||
|
||||
# Check if the address is a valid HNS address
|
||||
response = requests.post(get_node_api_url(), json={
|
||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_NODE_PORT}",json={
|
||||
"method": "validateaddress",
|
||||
"params": [address]
|
||||
}).json()
|
||||
@@ -412,6 +399,7 @@ def check_hip2(domain: str):
|
||||
return address
|
||||
|
||||
|
||||
|
||||
def send(account,address,amount):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -425,8 +413,9 @@ def send(account, address, amount):
|
||||
|
||||
response = hsw.rpc_walletPassphrase(password,10)
|
||||
# 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']['message'] != "Wallet is not encrypted.":
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
@@ -444,20 +433,11 @@ def send(account, address, amount):
|
||||
"tx": response['result']
|
||||
}
|
||||
|
||||
|
||||
def isOwnDomain(account,name: str):
|
||||
# Get domain
|
||||
domain_info = getDomain(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':
|
||||
domains = getDomains(account)
|
||||
for domain in domains:
|
||||
print(domain)
|
||||
if domain['name'] == name:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -473,19 +453,6 @@ def getDomain(domain: str):
|
||||
}
|
||||
return response['result']
|
||||
|
||||
def getAddressFromCoin(coinhash: str, coinindex = 0):
|
||||
# Get the address from the hash
|
||||
response = requests.get(get_node_api_url(f"coin/{coinhash}/{coinindex}"))
|
||||
if response.status_code != 200:
|
||||
print(f"Error getting address from coin: {response.text}")
|
||||
return "No Owner"
|
||||
data = response.json()
|
||||
if 'address' not in data:
|
||||
print(json.dumps(data, indent=4))
|
||||
return "No Owner"
|
||||
return data['address']
|
||||
|
||||
|
||||
def renewDomain(account,domain):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -500,7 +467,6 @@ def renewDomain(account, domain):
|
||||
response = hsw.sendRENEW(account_name,password,domain)
|
||||
return response
|
||||
|
||||
|
||||
def getDNS(domain: str):
|
||||
# Get the DNS
|
||||
response = hsd.rpc_getNameResource(domain)
|
||||
@@ -519,7 +485,6 @@ def getDNS(domain: str):
|
||||
return []
|
||||
return response['result']['records']
|
||||
|
||||
|
||||
def setDNS(account,domain,records):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -542,24 +507,10 @@ def setDNS(account, domain, records):
|
||||
for txt in record['txt']:
|
||||
TXTRecords.append(txt)
|
||||
elif record['type'] == 'NS':
|
||||
if 'value' in record:
|
||||
newRecords.append({
|
||||
'type': 'NS',
|
||||
'ns': record['value']
|
||||
})
|
||||
elif 'ns' in record:
|
||||
newRecords.append({
|
||||
'type': 'NS',
|
||||
'ns': record['ns']
|
||||
})
|
||||
else:
|
||||
return {
|
||||
'error': {
|
||||
'message': 'Invalid NS record'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
elif record['type'] in ['GLUE4','GLUE6',"SYNTH4","SYNTH6"]:
|
||||
newRecords.append({
|
||||
'type': record['type'],
|
||||
@@ -578,12 +529,10 @@ def setDNS(account, domain, records):
|
||||
response = hsw.sendUPDATE(account_name,password,domain,data)
|
||||
return response
|
||||
|
||||
|
||||
def register(account,domain):
|
||||
# Maybe add default dns records?
|
||||
return setDNS(account,domain,'[]')
|
||||
|
||||
|
||||
def getNodeSync():
|
||||
response = hsd.getInfo()
|
||||
if 'error' in response:
|
||||
@@ -593,7 +542,6 @@ def getNodeSync():
|
||||
sync = round(sync, 2)
|
||||
return sync
|
||||
|
||||
|
||||
def getWalletStatus():
|
||||
response = hsw.rpc_getWalletInfo()
|
||||
if 'error' in response and response['error'] != None:
|
||||
@@ -612,35 +560,12 @@ def getWalletStatus():
|
||||
return "Error wallet ahead of node"
|
||||
|
||||
|
||||
# Add a simple cache for bid data
|
||||
_bid_cache = {}
|
||||
_bid_cache_time = {}
|
||||
_cache_duration = 300 # Increased cache duration to 5 minutes for bids
|
||||
|
||||
# Add domain info cache
|
||||
_domain_info_cache = {}
|
||||
_domain_info_time = {}
|
||||
_domain_info_duration = 600 # Cache domain info for 10 minutes
|
||||
|
||||
# Add wallet authentication cache
|
||||
_wallet_auth_cache = {}
|
||||
_wallet_auth_time = {}
|
||||
_wallet_auth_duration = 300 # Increased to 5 minutes for wallet auth
|
||||
|
||||
def getBids(account, domain="NONE"):
|
||||
cache_key = f"{account}:{domain}"
|
||||
current_time = time.time()
|
||||
|
||||
# Return cached data if available and fresh
|
||||
if cache_key in _bid_cache and current_time - _bid_cache_time.get(cache_key, 0) < _cache_duration:
|
||||
return _bid_cache[cache_key]
|
||||
|
||||
try:
|
||||
if domain == "NONE":
|
||||
response = hsw.getWalletBids(account)
|
||||
else:
|
||||
response = hsw.getWalletBidsByName(domain,account)
|
||||
|
||||
# Add backup for bids with no value
|
||||
bids = []
|
||||
for bid in response:
|
||||
@@ -651,163 +576,28 @@ def getBids(account, domain="NONE"):
|
||||
if 'height' not in bid:
|
||||
bid['height'] = 0
|
||||
bids.append(bid)
|
||||
|
||||
# Cache the results
|
||||
_bid_cache[cache_key] = bids
|
||||
_bid_cache_time[cache_key] = current_time
|
||||
|
||||
return bids
|
||||
except Exception as e:
|
||||
print(f"Error fetching bids: {str(e)}")
|
||||
return []
|
||||
|
||||
def _fetch_domain_info(domain):
|
||||
"""Helper function to fetch domain info with caching"""
|
||||
current_time = time.time()
|
||||
|
||||
# Check cache first
|
||||
if (domain in _domain_info_cache and
|
||||
current_time - _domain_info_time.get(domain, 0) < _domain_info_duration):
|
||||
return _domain_info_cache[domain]
|
||||
|
||||
# Fetch domain info
|
||||
domain_info = getDomain(domain)
|
||||
|
||||
# Store in cache
|
||||
_domain_info_cache[domain] = domain_info
|
||||
_domain_info_time[domain] = current_time
|
||||
|
||||
return domain_info
|
||||
|
||||
def _fetch_domain_batch(domains, max_workers=10):
|
||||
"""Fetch multiple domains in parallel"""
|
||||
results = {}
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||
# Create a mapping of futures to domains
|
||||
future_to_domain = {executor.submit(_fetch_domain_info, domain): domain for domain in domains}
|
||||
|
||||
# Process as they complete
|
||||
for future in concurrent.futures.as_completed(future_to_domain):
|
||||
domain = future_to_domain[future]
|
||||
try:
|
||||
results[domain] = future.result()
|
||||
except Exception as e:
|
||||
print(f"Error fetching domain {domain}: {str(e)}")
|
||||
results[domain] = {"error": str(e)}
|
||||
|
||||
return results
|
||||
|
||||
def getPossibleOutbids(account):
|
||||
# Get all bids
|
||||
bids = getBids(account)
|
||||
if not bids or 'error' in bids:
|
||||
return []
|
||||
|
||||
# Get current height
|
||||
current_height = getBlockHeight()
|
||||
|
||||
# Sort out bids older than 720 blocks and extract domain names
|
||||
filtered_bids = []
|
||||
domains_to_check = set()
|
||||
|
||||
for bid in bids:
|
||||
if (current_height - bid['height']) <= 720:
|
||||
filtered_bids.append(bid)
|
||||
domains_to_check.add(bid['name'])
|
||||
|
||||
if not domains_to_check:
|
||||
return []
|
||||
|
||||
# Fetch all domain info in parallel
|
||||
domain_info_map = _fetch_domain_batch(domains_to_check)
|
||||
|
||||
# Pre-filter domains in bidding state
|
||||
bidding_domains = {
|
||||
domain: info for domain, info in domain_info_map.items()
|
||||
if ('info' in info and 'state' in info['info'] and
|
||||
info['info']['state'] == "BIDDING")
|
||||
}
|
||||
|
||||
# Process the results
|
||||
possible_outbids = []
|
||||
processed_domains = set()
|
||||
|
||||
# Group bids by domain name for efficient processing
|
||||
bids_by_domain = {}
|
||||
for bid in filtered_bids:
|
||||
domain = bid['name']
|
||||
if domain not in bids_by_domain:
|
||||
bids_by_domain[domain] = []
|
||||
bids_by_domain[domain].append(bid)
|
||||
|
||||
# Analyze each domain in bidding state
|
||||
for domain, info in bidding_domains.items():
|
||||
if domain in processed_domains or domain not in bids_by_domain:
|
||||
continue
|
||||
|
||||
processed_domains.add(domain)
|
||||
|
||||
# Get all bids for this domain in one call
|
||||
domain_bids = getBids(account, domain)
|
||||
|
||||
# Find the highest bid we've made
|
||||
our_highest_bid = max(
|
||||
(bid['value'] for bid in domain_bids if bid.get("own", False)),
|
||||
default=0
|
||||
)
|
||||
|
||||
# Quick check if any unrevealed bids could outbid us
|
||||
if any(
|
||||
bid["lockup"] > our_highest_bid
|
||||
for bid in domain_bids
|
||||
if not bid.get("own", False) and bid.get('value', 0) == -1000000
|
||||
):
|
||||
possible_outbids.append(domain)
|
||||
|
||||
return possible_outbids
|
||||
|
||||
def getReveals(account,domain):
|
||||
return hsw.getWalletRevealsByName(domain,account)
|
||||
|
||||
def getPendingReveals(account):
|
||||
bids = getBids(account)
|
||||
# Only get domains in REVEAL state to reduce API calls
|
||||
domains = [d for d in getDomains(account, False) if d['state'] == "REVEAL"]
|
||||
|
||||
if not domains: # Early return if no domains in REVEAL state
|
||||
return []
|
||||
|
||||
domains = getDomains(account,False)
|
||||
pending = []
|
||||
|
||||
# Create a dictionary for O(1) lookups
|
||||
domain_names = {domain['name']: domain for domain in domains}
|
||||
|
||||
# Group bids by name to batch process reveals
|
||||
bids_by_name = {}
|
||||
for domain in domains:
|
||||
if domain['state'] == "REVEAL":
|
||||
reveals = getReveals(account,domain['name'])
|
||||
for bid in bids:
|
||||
if bid['name'] in domain_names:
|
||||
if bid['name'] not in bids_by_name:
|
||||
bids_by_name[bid['name']] = []
|
||||
bids_by_name[bid['name']].append(bid)
|
||||
if bid['name'] == domain['name']:
|
||||
state_found = False
|
||||
for reveal in reveals:
|
||||
if reveal['own'] == True:
|
||||
if bid['value'] == reveal['value']:
|
||||
state_found = True
|
||||
|
||||
# Fetch reveals for each domain once
|
||||
reveals_by_name = {}
|
||||
for domain_name in bids_by_name:
|
||||
reveals_by_name[domain_name] = getReveals(account, domain_name)
|
||||
|
||||
# Check each bid against the reveals
|
||||
for domain_name, domain_bids in bids_by_name.items():
|
||||
domain_reveals = reveals_by_name[domain_name]
|
||||
for bid in domain_bids:
|
||||
# Check if this bid has been revealed
|
||||
bid_revealed = any(
|
||||
reveal['own'] == True and bid['value'] == reveal['value']
|
||||
for reveal in domain_reveals
|
||||
)
|
||||
|
||||
if not bid_revealed:
|
||||
if not state_found:
|
||||
pending.append(bid)
|
||||
|
||||
return pending
|
||||
|
||||
|
||||
@@ -820,53 +610,35 @@ def getPendingRedeems(account, password):
|
||||
|
||||
pending = []
|
||||
try:
|
||||
# Collect all nameHashes first
|
||||
name_hashes = []
|
||||
for output in tx['result']['outputs']:
|
||||
if output['covenant']['type'] != 5:
|
||||
continue
|
||||
if output['covenant']['action'] != "REDEEM":
|
||||
continue
|
||||
name_hashes.append(output['covenant']['items'][0])
|
||||
|
||||
# Batch processing name hashes
|
||||
name_lookup = {}
|
||||
for name_hash in name_hashes:
|
||||
name = hsd.rpc_getNameByHash(name_hash)
|
||||
nameHash = output['covenant']['items'][0]
|
||||
# Try to get the name from hash
|
||||
name = hsd.rpc_getNameByHash(nameHash)
|
||||
if name['error']:
|
||||
pending.append(name_hash)
|
||||
pending.append(nameHash)
|
||||
else:
|
||||
pending.append(name['result'])
|
||||
name_lookup[name_hash] = name['result']
|
||||
|
||||
except Exception as e:
|
||||
print(f"Failed to parse redeems: {str(e)}")
|
||||
except:
|
||||
print("Failed to parse redeems")
|
||||
|
||||
return pending
|
||||
|
||||
|
||||
def getPendingRegisters(account):
|
||||
bids = getBids(account)
|
||||
domains = getDomains(account,False)
|
||||
|
||||
# Create dictionaries for O(1) lookups
|
||||
bids_by_name = {}
|
||||
for bid in bids:
|
||||
if bid['name'] not in bids_by_name:
|
||||
bids_by_name[bid['name']] = []
|
||||
bids_by_name[bid['name']].append(bid)
|
||||
|
||||
pending = []
|
||||
for domain in domains:
|
||||
if domain['state'] == "CLOSED" and domain['registered'] == False:
|
||||
if domain['name'] in bids_by_name:
|
||||
for bid in bids_by_name[domain['name']]:
|
||||
for bid in bids:
|
||||
if bid['name'] == domain['name']:
|
||||
if bid['value'] == domain['highest']:
|
||||
pending.append(bid)
|
||||
|
||||
return pending
|
||||
|
||||
|
||||
def getPendingFinalizes(account,password):
|
||||
tx = createBatch(f'{account}:{password}',[["FINALIZE"]])
|
||||
if 'error' in tx:
|
||||
@@ -874,26 +646,20 @@ def getPendingFinalizes(account, password):
|
||||
|
||||
pending = []
|
||||
try:
|
||||
# Collect all nameHashes first
|
||||
name_hashes = []
|
||||
for output in tx['outputs']:
|
||||
if output['covenant']['type'] != 10:
|
||||
continue
|
||||
if output['covenant']['action'] != "FINALIZE":
|
||||
continue
|
||||
name_hashes.append(output['covenant']['items'][0])
|
||||
|
||||
# Batch lookup for name hashes
|
||||
for name_hash in name_hashes:
|
||||
name = hsd.rpc_getNameByHash(name_hash)
|
||||
nameHash = output['covenant']['items'][0]
|
||||
# Try to get the name from hash
|
||||
name = hsd.rpc_getNameByHash(nameHash)
|
||||
if name['error']:
|
||||
pending.append(name_hash)
|
||||
pending.append(nameHash)
|
||||
else:
|
||||
pending.append(name['result'])
|
||||
|
||||
except Exception as e:
|
||||
print(f"Failed to parse finalizes: {str(e)}")
|
||||
|
||||
except:
|
||||
print("Failed to parse finalizes")
|
||||
return pending
|
||||
|
||||
|
||||
@@ -931,7 +697,6 @@ def revealAuction(account, domain):
|
||||
"error": str(e)
|
||||
}
|
||||
|
||||
|
||||
def revealAll(account):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -950,14 +715,9 @@ def revealAll(account):
|
||||
return
|
||||
response = hsw.rpc_walletPassphrase(password,10)
|
||||
if response['error'] is not None:
|
||||
if response['error']['message'] != "Wallet is not encrypted.":
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
return requests.post(get_wallet_api_url(), json={"method": "sendbatch", "params": [[["REVEAL"]]]}).json()
|
||||
return requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}",json={"method": "sendbatch","params": [[["REVEAL"]]]}).json()
|
||||
except Exception as e:
|
||||
return {
|
||||
"error": {
|
||||
@@ -965,7 +725,6 @@ def revealAll(account):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def redeemAll(account):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -984,14 +743,9 @@ def redeemAll(account):
|
||||
return
|
||||
response = hsw.rpc_walletPassphrase(password,10)
|
||||
if response['error'] is not None:
|
||||
if response['error']['message'] != "Wallet is not encrypted.":
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
return requests.post(get_wallet_api_url(), json={"method": "sendbatch", "params": [[["REDEEM"]]]}).json()
|
||||
return requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}",json={"method": "sendbatch","params": [[["REDEEM"]]]}).json()
|
||||
except Exception as e:
|
||||
return {
|
||||
"error": {
|
||||
@@ -999,7 +753,6 @@ def redeemAll(account):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def registerAll(account):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -1024,7 +777,6 @@ def registerAll(account):
|
||||
batch.append(["UPDATE",domain['name'],{"records":[]}])
|
||||
return sendBatch(account,batch)
|
||||
|
||||
|
||||
def finalizeAll(account):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -1038,7 +790,6 @@ def finalizeAll(account):
|
||||
|
||||
return sendBatch(account,[["FINALIZE"]])
|
||||
|
||||
|
||||
def rescan_auction(account,domain):
|
||||
# Get height of the start of the auction
|
||||
response = hsw.rpc_selectWallet(account)
|
||||
@@ -1103,6 +854,7 @@ def openAuction(account, domain):
|
||||
}
|
||||
|
||||
|
||||
|
||||
def transfer(account,domain,address):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -1124,7 +876,6 @@ def transfer(account, domain, address):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def finalize(account,domain):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -1146,7 +897,6 @@ def finalize(account, domain):
|
||||
}
|
||||
response = hsw.rpc_walletPassphrase(password,10)
|
||||
if response['error'] is not None:
|
||||
if response['error']['message'] != "Wallet is not encrypted.":
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
@@ -1161,7 +911,6 @@ def finalize(account, domain):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def cancelTransfer(account,domain):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -1183,7 +932,6 @@ def cancelTransfer(account, domain):
|
||||
}
|
||||
response = hsw.rpc_walletPassphrase(password,10)
|
||||
if response['error'] is not None:
|
||||
if response['error']['message'] != "Wallet is not encrypted.":
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
@@ -1198,7 +946,6 @@ def cancelTransfer(account, domain):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def revoke(account,domain):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
@@ -1220,7 +967,6 @@ def revoke(account, domain):
|
||||
}
|
||||
response = hsw.rpc_walletPassphrase(password,10)
|
||||
if response['error'] is not None:
|
||||
if response['error']['message'] != "Wallet is not encrypted.":
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
@@ -1235,109 +981,16 @@ def revoke(account, domain):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def _prepare_wallet_for_batch(account_name, password):
|
||||
"""Helper function to prepare wallet for batch operations with caching"""
|
||||
cache_key = f"{account_name}:{password}"
|
||||
current_time = time.time()
|
||||
|
||||
# Return cached authentication if available and fresh
|
||||
if (cache_key in _wallet_auth_cache and
|
||||
current_time - _wallet_auth_time.get(cache_key, 0) < _wallet_auth_duration):
|
||||
return _wallet_auth_cache[cache_key]
|
||||
|
||||
# Select and unlock wallet
|
||||
result = {'success': False, 'error': None}
|
||||
|
||||
# Try to select the wallet
|
||||
select_response = hsw.rpc_selectWallet(account_name)
|
||||
if select_response['error'] is not None:
|
||||
result['error'] = {"message": select_response['error']['message']}
|
||||
return result
|
||||
|
||||
# Try to unlock the wallet
|
||||
unlock_response = hsw.rpc_walletPassphrase(password, 30) # Increased timeout to reduce future unlocks
|
||||
if (unlock_response['error'] is not None and
|
||||
unlock_response['error']['message'] != "Wallet is not encrypted."):
|
||||
result['error'] = {"message": unlock_response['error']['message']}
|
||||
return result
|
||||
|
||||
# Authentication successful
|
||||
result['success'] = True
|
||||
|
||||
# Cache the authentication result
|
||||
_wallet_auth_cache[cache_key] = result
|
||||
_wallet_auth_time[cache_key] = current_time
|
||||
|
||||
return result
|
||||
|
||||
def _execute_batch_operation(account_name, batch, operation_type="sendbatch"):
|
||||
"""Execute a batch operation with the specified wallet"""
|
||||
# Make the batch request
|
||||
try:
|
||||
response = requests.post(
|
||||
get_wallet_api_url(),
|
||||
json={"method": operation_type, "params": [batch]},
|
||||
timeout=30 # Add timeout to prevent hanging
|
||||
).json()
|
||||
|
||||
if response['error'] is not None:
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
}
|
||||
}
|
||||
response = hsw.rpc_walletPassphrase(password, 10)
|
||||
if response['error'] is not None:
|
||||
if response['error']['message'] != "Wallet is not encrypted.":
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
}
|
||||
}
|
||||
response = requests.post(get_wallet_api_url(), json={
|
||||
"method": "sendbatch",
|
||||
"params": [batch]
|
||||
}).json()
|
||||
if response['error'] is not None:
|
||||
return response
|
||||
if 'result' not in response:
|
||||
return {"error": {"message": "No result"}}
|
||||
|
||||
return response['result']
|
||||
except Exception as e:
|
||||
return {"error": {"message": str(e)}}
|
||||
|
||||
def sendBatch(account, batch):
|
||||
account_name = check_account(account)
|
||||
if account_name == False:
|
||||
return {"error": {"message": "Invalid account"}}
|
||||
|
||||
password = ":".join(account.split(":")[1:])
|
||||
|
||||
# Prepare the wallet (this uses caching)
|
||||
auth_result = _prepare_wallet_for_batch(account_name, password)
|
||||
if not auth_result['success']:
|
||||
return auth_result['error']
|
||||
|
||||
# Execute the batch operation
|
||||
return _execute_batch_operation(account_name, batch, "sendbatch")
|
||||
|
||||
def createBatch(account, batch):
|
||||
account_name = check_account(account)
|
||||
if account_name == False:
|
||||
return {"error": {"message": "Invalid account"}}
|
||||
|
||||
password = ":".join(account.split(":")[1:])
|
||||
|
||||
# Prepare the wallet (this uses caching)
|
||||
auth_result = _prepare_wallet_for_batch(account_name, password)
|
||||
if not auth_result['success']:
|
||||
return auth_result['error']
|
||||
|
||||
# Execute the batch operation
|
||||
return _execute_batch_operation(account_name, batch, "createbatch")
|
||||
|
||||
return {
|
||||
"error": {
|
||||
"message": "Invalid account"
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
response = hsw.rpc_selectWallet(account_name)
|
||||
@@ -1349,13 +1002,59 @@ def createBatch(account, batch):
|
||||
}
|
||||
response = hsw.rpc_walletPassphrase(password,10)
|
||||
if response['error'] is not None:
|
||||
if response['error']['message'] != "Wallet is not encrypted.":
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
}
|
||||
}
|
||||
response = requests.post(get_wallet_api_url(), json={
|
||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}",json={
|
||||
"method": "sendbatch",
|
||||
"params": [batch]
|
||||
}).json()
|
||||
if response['error'] is not None:
|
||||
return response
|
||||
if 'result' not in response:
|
||||
return {
|
||||
"error": {
|
||||
"message": "No result"
|
||||
}
|
||||
}
|
||||
|
||||
return response['result']
|
||||
except Exception as e:
|
||||
return {
|
||||
"error": {
|
||||
"message": str(e)
|
||||
}
|
||||
}
|
||||
|
||||
def createBatch(account, batch):
|
||||
account_name = check_account(account)
|
||||
password = ":".join(account.split(":")[1:])
|
||||
|
||||
if account_name == False:
|
||||
return {
|
||||
"error": {
|
||||
"message": "Invalid account"
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
response = hsw.rpc_selectWallet(account_name)
|
||||
if response['error'] is not None:
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
}
|
||||
}
|
||||
response = hsw.rpc_walletPassphrase(password,10)
|
||||
if response['error'] is not None:
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
}
|
||||
}
|
||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}",json={
|
||||
"method": "createbatch",
|
||||
"params": [batch]
|
||||
}).json()
|
||||
@@ -1389,7 +1088,6 @@ def rescan():
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def resendTXs():
|
||||
try:
|
||||
response = hsw.walletResend()
|
||||
@@ -1402,6 +1100,7 @@ def resendTXs():
|
||||
}
|
||||
|
||||
|
||||
|
||||
def zapTXs(account):
|
||||
age = 60 * 20 # 20 minutes
|
||||
|
||||
@@ -1415,7 +1114,7 @@ def zapTXs(account):
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(get_wallet_api_url(f"/wallet/{account_name}/zap"),
|
||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}/wallet/{account_name}/zap",
|
||||
json={"age": age,
|
||||
"account": "default"
|
||||
})
|
||||
@@ -1438,7 +1137,9 @@ def getxPub(account):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try:
|
||||
print(account_name)
|
||||
response = hsw.getAccountInfo(account_name,"default")
|
||||
if 'error' in response:
|
||||
return {
|
||||
@@ -1468,6 +1169,7 @@ def signMessage(account, domain, message):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try:
|
||||
response = hsw.rpc_selectWallet(account_name)
|
||||
if response['error'] is not None:
|
||||
@@ -1478,7 +1180,6 @@ def signMessage(account, domain, message):
|
||||
}
|
||||
response = hsw.rpc_walletPassphrase(password,10)
|
||||
if response['error'] is not None:
|
||||
if response['error']['message'] != "Wallet is not encrypted.":
|
||||
return {
|
||||
"error": {
|
||||
"message": response['error']['message']
|
||||
@@ -1493,7 +1194,6 @@ def signMessage(account, domain, message):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def verifyMessageWithName(domain,signature,message):
|
||||
try:
|
||||
response = hsd.rpc_verifyMessageWithName(domain,signature,message)
|
||||
@@ -1515,7 +1215,6 @@ def verifyMessage(address, signature, message):
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
def generateReport(account,format="{name},{expiry},{value},{maxBid}"):
|
||||
domains = getDomains(account)
|
||||
|
||||
@@ -1541,28 +1240,5 @@ def generateReport(account, format="{name},{expiry},{value},{maxBid}"):
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
def convertHNS(value: int):
|
||||
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
|
||||
|
||||
@@ -139,6 +139,35 @@ def resolve_TLSA_with_doh(query_name, doh_url="https://hnsdoh.com/dns-query"):
|
||||
return tlsa
|
||||
|
||||
|
||||
def niami_info(domain: str):
|
||||
response = requests.get(f"https://api.niami.io/hsd/{domain}")
|
||||
if response.status_code != 200:
|
||||
return False
|
||||
|
||||
response = response.json()
|
||||
if response["data"]["owner_tx_data"] is not None:
|
||||
output = {
|
||||
"owner": response["data"]["owner_tx_data"]["address"]
|
||||
}
|
||||
else:
|
||||
output = {
|
||||
"owner": None
|
||||
}
|
||||
|
||||
if 'dnsData' in response["data"]:
|
||||
output["dns"] = response["data"]["dnsData"]
|
||||
else:
|
||||
output["dns"] = []
|
||||
|
||||
transactions = requests.get(f"https://api.niami.io/txs/{domain}")
|
||||
if transactions.status_code != 200:
|
||||
return False
|
||||
|
||||
transactions = transactions.json()
|
||||
output["txs"] = transactions["txs"]
|
||||
return output
|
||||
|
||||
|
||||
def emoji_to_punycode(emoji):
|
||||
try:
|
||||
return emoji.encode("idna").decode("ascii")
|
||||
|
||||
@@ -2,4 +2,4 @@ HSD_API=123480615465636893475aCwyaae6s45
|
||||
HSD_IP=localhost
|
||||
THEME=black
|
||||
SHOW_EXPIRED=false
|
||||
EXPLORER_TX=https://shakeshift.com/transaction/
|
||||
EXPLORER_TX=https://niami.io/tx/
|
||||
327
main.py
327
main.py
@@ -16,8 +16,6 @@ import importlib
|
||||
import plugin as plugins_module
|
||||
import gitinfo
|
||||
import datetime
|
||||
import functools
|
||||
import time
|
||||
|
||||
dotenv.load_dotenv()
|
||||
|
||||
@@ -32,38 +30,6 @@ revokeCheck = random.randint(100000,999999)
|
||||
|
||||
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"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Add a cache for transactions with a timeout
|
||||
tx_cache = {}
|
||||
TX_CACHE_TIMEOUT = 60*5 # Cache timeout in seconds
|
||||
|
||||
# Add a cache for outbids with a timeout
|
||||
outbids_cache = {}
|
||||
OUTBIDS_CACHE_TIMEOUT = 60*2 # Cache timeout in seconds
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
# Check if the user is logged in
|
||||
@@ -109,10 +75,7 @@ def transactions():
|
||||
return redirect("/login")
|
||||
|
||||
account = account_module.check_account(request.cookies.get("account"))
|
||||
if not account:
|
||||
return redirect("/logout")
|
||||
|
||||
# Get the page parameter
|
||||
# Get the transactions
|
||||
page = request.args.get('page')
|
||||
try:
|
||||
page = int(page)
|
||||
@@ -122,9 +85,12 @@ def transactions():
|
||||
if page < 1:
|
||||
page = 1
|
||||
|
||||
# Return the template with loading state - transactions will be loaded via AJAX
|
||||
transactions = account_module.getTransactions(account,page)
|
||||
txCount = len(transactions)
|
||||
transactions = render.transactions(transactions)
|
||||
return render_template("tx.html", account=account,
|
||||
page=page, txCount=0)
|
||||
tx=transactions,
|
||||
page=page,txCount=txCount)
|
||||
|
||||
|
||||
@app.route('/send')
|
||||
@@ -212,15 +178,7 @@ def sendConfirmed():
|
||||
address = request.args.get("address")
|
||||
amount = float(request.args.get("amount"))
|
||||
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))
|
||||
else:
|
||||
return redirect("/send?message=" + str(response['error']) + "&address=" + address + "&amount=" + str(amount))
|
||||
|
||||
# If error is a string
|
||||
if 'error' in response:
|
||||
return redirect("/send?message=" + response['error'] + "&address=" + address + "&amount=" + str(amount))
|
||||
|
||||
return redirect("/success?tx=" + response['tx'])
|
||||
@@ -322,12 +280,8 @@ def auctions():
|
||||
sort_time = direction
|
||||
sort_time_next = reverseDirection(direction)
|
||||
|
||||
# Check if bids list is empty to avoid IndexError
|
||||
if not bids:
|
||||
domains = sorted(domains, key=lambda k: k['height'],reverse=reverse)
|
||||
sortbyDomain = True
|
||||
# If older HSD version sort by domain height
|
||||
elif bids[0]['height'] == 0:
|
||||
if bids[0]['height'] == 0:
|
||||
domains = sorted(domains, key=lambda k: k['height'],reverse=reverse)
|
||||
sortbyDomain = True
|
||||
else:
|
||||
@@ -338,27 +292,7 @@ def auctions():
|
||||
sort_domain = direction
|
||||
sort_domain_next = reverseDirection(direction)
|
||||
|
||||
# Check if outbids set to true
|
||||
outbids = request.args.get("outbids")
|
||||
if outbids is not None and outbids.lower() == "true":
|
||||
# Check cache before making expensive call
|
||||
cache_key = f"outbids_{account}"
|
||||
current_time = time.time()
|
||||
|
||||
if cache_key in outbids_cache and (current_time - outbids_cache[cache_key]['time'] < OUTBIDS_CACHE_TIMEOUT):
|
||||
outbids = outbids_cache[cache_key]['data']
|
||||
else:
|
||||
# Get outbid domains
|
||||
outbids = account_module.getPossibleOutbids(account)
|
||||
# Store in cache
|
||||
outbids_cache[cache_key] = {
|
||||
'data': outbids,
|
||||
'time': current_time
|
||||
}
|
||||
else:
|
||||
outbids = []
|
||||
|
||||
bidsHtml = render.bidDomains(bids,domains,sortbyDomain,outbids)
|
||||
bidsHtml = render.bidDomains(bids,domains,sortbyDomain)
|
||||
plugins = ""
|
||||
message = ''
|
||||
if 'message' in request.args:
|
||||
@@ -386,12 +320,11 @@ def revealAllBids():
|
||||
return redirect("/logout")
|
||||
|
||||
response = account_module.revealAll(request.cookies.get("account"))
|
||||
# Simplified error handling
|
||||
if 'error' in response and response['error']:
|
||||
error_msg = response['error'].get('message', str(response['error']))
|
||||
if error_msg == "Nothing to do.":
|
||||
if 'error' in response:
|
||||
if response['error'] != None:
|
||||
if response['error']['message'] == "Nothing to do.":
|
||||
return redirect("/auctions?message=No reveals pending")
|
||||
return redirect("/auctions?message=" + error_msg)
|
||||
return redirect("/auctions?message=" + response['error']['message'])
|
||||
|
||||
return redirect("/success?tx=" + response['result']['hash'])
|
||||
|
||||
@@ -488,21 +421,20 @@ def search():
|
||||
|
||||
if 'error' in domain:
|
||||
return render_template("search.html", account=account,
|
||||
rendered=renderDomain(search_term),
|
||||
|
||||
search_term=search_term, domain=domain['error'],plugins=plugins)
|
||||
|
||||
if domain['info'] is None:
|
||||
return render_template("search.html", account=account,
|
||||
rendered=renderDomain(search_term),
|
||||
|
||||
search_term=search_term,domain=search_term,
|
||||
state="AVAILABLE", next="Available Now",plugins=plugins)
|
||||
|
||||
state = domain['info']['state']
|
||||
stats = domain['info']['stats']
|
||||
if state == 'CLOSED':
|
||||
if domain['info']['registered']:
|
||||
state = 'REGISTERED'
|
||||
expires = stats['daysUntilExpire']
|
||||
expires = domain['info']['stats']['daysUntilExpire']
|
||||
next = f"Expires in ~{expires} days"
|
||||
else:
|
||||
state = 'AVAILABLE'
|
||||
@@ -510,36 +442,38 @@ def search():
|
||||
elif state == "REVOKED":
|
||||
next = "Available Now"
|
||||
elif state == 'OPENING':
|
||||
next = f"Bidding opens in {str(stats['blocksUntilBidding'])} blocks (~{blocks_to_time(stats['blocksUntilBidding'])})"
|
||||
next = "Bidding opens in ~" + str(domain['info']['stats']['blocksUntilBidding']) + " blocks"
|
||||
elif state == 'BIDDING':
|
||||
next = f"Reveal in {str(stats['blocksUntilReveal'])} blocks (~{blocks_to_time(stats['blocksUntilReveal'])})"
|
||||
next = "Reveal in ~" + str(domain['info']['stats']['blocksUntilReveal']) + " blocks"
|
||||
elif state == 'REVEAL':
|
||||
next = f"Reveal ends in {str(stats['blocksUntilClose'])} blocks (~{blocks_to_time(stats['blocksUntilClose'])})"
|
||||
next = "Reveal ends in ~" + str(domain['info']['stats']['blocksUntilClose']) + " blocks"
|
||||
|
||||
|
||||
|
||||
domain_info = account_module.getDomain(search_term)
|
||||
domain_info = domainLookup.niami_info(search_term)
|
||||
owner = 'Unknown'
|
||||
dns = []
|
||||
txs = []
|
||||
|
||||
if domain_info:
|
||||
# Check if info and info.owner
|
||||
if 'info' in domain_info and 'owner' in domain_info['info']:
|
||||
owner = account_module.getAddressFromCoin(domain_info['info']['owner']['hash'],domain_info['info']['owner']['index'])
|
||||
owner = domain_info['owner']
|
||||
dns = domain_info['dns']
|
||||
txs = domain_info['txs']
|
||||
|
||||
dns = account_module.getDNS(search_term)
|
||||
|
||||
if account_module.isOwnDomain(account, search_term):
|
||||
own_domains = account_module.getDomains(account)
|
||||
own_domains = [x['name'] for x in own_domains]
|
||||
own_domains = [x.lower() for x in own_domains]
|
||||
if search_term in own_domains:
|
||||
owner = "You"
|
||||
|
||||
dns = render.dns(dns)
|
||||
txs = render.txs(txs)
|
||||
|
||||
return render_template("search.html", account=account,
|
||||
rendered=renderDomain(search_term),
|
||||
|
||||
search_term=search_term,domain=domain['info']['name'],
|
||||
raw=domain,state=state, next=next, owner=owner,
|
||||
dns=dns,plugins=plugins)
|
||||
dns=dns, txs=txs,plugins=plugins)
|
||||
|
||||
@app.route('/manage/<domain>')
|
||||
def manage(domain: str):
|
||||
@@ -553,19 +487,19 @@ def manage(domain: str):
|
||||
|
||||
domain = domain.lower()
|
||||
|
||||
if not account_module.isOwnDomain(account, domain):
|
||||
own_domains = account_module.getDomains(account)
|
||||
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)
|
||||
|
||||
domain_info = account_module.getDomain(domain)
|
||||
if 'error' in domain_info:
|
||||
return render_template("manage.html", account=account,
|
||||
rendered=renderDomain(domain),
|
||||
|
||||
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']
|
||||
else:
|
||||
expiry = "Unknown"
|
||||
dns = account_module.getDNS(domain)
|
||||
raw_dns = str(dns).replace("'",'"')
|
||||
dns = render.dns(dns)
|
||||
@@ -599,7 +533,7 @@ def manage(domain: str):
|
||||
|
||||
|
||||
return render_template("manage.html", account=account,
|
||||
rendered=renderDomain(domain),
|
||||
|
||||
error=errorMessage, address=address,
|
||||
domain=domain,expiry=expiry, dns=dns,
|
||||
raw_dns=urllib.parse.quote(raw_dns),
|
||||
@@ -617,6 +551,7 @@ def finalize(domain: str):
|
||||
return redirect("/logout")
|
||||
|
||||
domain = domain.lower()
|
||||
print(domain)
|
||||
response = account_module.finalize(request.cookies.get("account"),domain)
|
||||
if response['error'] != None:
|
||||
print(response)
|
||||
@@ -635,6 +570,7 @@ def cancelTransfer(domain: str):
|
||||
return redirect("/logout")
|
||||
|
||||
domain = domain.lower()
|
||||
print(domain)
|
||||
response = account_module.cancelTransfer(request.cookies.get("account"),domain)
|
||||
if 'error' in response:
|
||||
if response['error'] != None:
|
||||
@@ -725,7 +661,10 @@ def editPage(domain: str):
|
||||
|
||||
domain = domain.lower()
|
||||
|
||||
if not account_module.isOwnDomain(account, domain):
|
||||
own_domains = account_module.getDomains(account)
|
||||
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)
|
||||
|
||||
|
||||
@@ -771,7 +710,7 @@ def editPage(domain: str):
|
||||
|
||||
|
||||
return render_template("edit.html", account=account,
|
||||
rendered=renderDomain(domain),
|
||||
|
||||
domain=domain, error=errorMessage,
|
||||
dns=dns,raw_dns=urllib.parse.quote(raw_dns))
|
||||
|
||||
@@ -917,7 +856,7 @@ def auction(domain):
|
||||
|
||||
if 'error' in domainInfo:
|
||||
return render_template("auction.html", account=account,
|
||||
rendered=renderDomain(search_term),
|
||||
|
||||
search_term=search_term, domain=domainInfo['error'],
|
||||
error=error)
|
||||
|
||||
@@ -928,7 +867,7 @@ def auction(domain):
|
||||
else:
|
||||
next_action = f'<a href="/auction/{domain}/open">Open Auction</a>'
|
||||
return render_template("auction.html", account=account,
|
||||
rendered=renderDomain(search_term),
|
||||
|
||||
search_term=search_term,domain=search_term,next_action=next_action,
|
||||
state="AVAILABLE", next="Open Auction",
|
||||
error=error)
|
||||
@@ -946,9 +885,10 @@ def auction(domain):
|
||||
# Get TX
|
||||
revealInfo = account_module.getRevealTX(reveal)
|
||||
reveal['bid'] = revealInfo
|
||||
print(revealInfo)
|
||||
bids = render.bids(bids,reveals)
|
||||
|
||||
stats = domainInfo['info']['stats'] if 'stats' in domainInfo['info'] else {}
|
||||
|
||||
if state == 'CLOSED':
|
||||
if not domainInfo['info']['registered']:
|
||||
if account_module.isOwnDomain(account,domain):
|
||||
@@ -967,27 +907,20 @@ def auction(domain):
|
||||
expires = domainInfo['info']['stats']['daysUntilExpire']
|
||||
next = f"Expires in ~{expires} days"
|
||||
|
||||
if account_module.isOwnDomain(account,domain):
|
||||
own_domains = account_module.getDomains(account)
|
||||
own_domains = [x['name'] for x in own_domains]
|
||||
own_domains = [x.lower() for x in own_domains]
|
||||
if search_term in own_domains:
|
||||
next_action = f'<a href="/manage/{domain}">Manage</a>'
|
||||
elif state == "REVOKED":
|
||||
next = "Available Now"
|
||||
next_action = f'<a href="/auction/{domain}/open">Open Auction</a>'
|
||||
elif state == 'OPENING':
|
||||
next = f"Bidding opens in {str(stats['blocksUntilBidding'])} blocks (~{blocks_to_time(stats['blocksUntilBidding'])})"
|
||||
next = "Bidding opens in ~" + str(domainInfo['info']['stats']['blocksUntilBidding']) + " blocks"
|
||||
elif state == 'BIDDING':
|
||||
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"
|
||||
|
||||
|
||||
next = "Reveal in ~" + str(domainInfo['info']['stats']['blocksUntilReveal']) + " blocks"
|
||||
elif state == 'REVEAL':
|
||||
next = f"Reveal ends in {str(stats['blocksUntilClose'])} blocks (~{blocks_to_time(stats['blocksUntilClose'])})"
|
||||
next = "Reveal ends in ~" + str(domainInfo['info']['stats']['blocksUntilClose']) + " blocks"
|
||||
next_action = f'<a href="/auction/{domain}/reveal">Reveal All</a>'
|
||||
|
||||
message = ''
|
||||
@@ -996,7 +929,7 @@ def auction(domain):
|
||||
|
||||
|
||||
return render_template("auction.html", account=account,
|
||||
rendered=renderDomain(search_term),
|
||||
|
||||
search_term=search_term,domain=domainInfo['info']['name'],
|
||||
raw=domainInfo,state=state, next=next,
|
||||
next_action=next_action, bids=bids,error=message)
|
||||
@@ -1014,6 +947,7 @@ def rescan_auction(domain):
|
||||
domain = domain.lower()
|
||||
|
||||
response = account_module.rescan_auction(account,domain)
|
||||
print(response)
|
||||
return redirect("/auction/" + domain)
|
||||
|
||||
@app.route('/auction/<domain>/bid')
|
||||
@@ -1089,7 +1023,7 @@ def bid_confirm(domain):
|
||||
response = account_module.bid(request.cookies.get("account"),domain,
|
||||
float(bid),
|
||||
float(blind))
|
||||
|
||||
print(response)
|
||||
if 'error' in response:
|
||||
return redirect("/auction/" + domain + "?error=" + response['error']['message'])
|
||||
|
||||
@@ -1111,7 +1045,7 @@ def open_auction(domain):
|
||||
if 'error' in response:
|
||||
if response['error'] != None:
|
||||
return redirect("/auction/" + domain + "?error=" + response['error']['message'])
|
||||
|
||||
print(response)
|
||||
return redirect("/success?tx=" + response['hash'])
|
||||
|
||||
@app.route('/auction/<domain>/reveal')
|
||||
@@ -1120,12 +1054,11 @@ def reveal_auction(domain):
|
||||
if request.cookies.get("account") is None:
|
||||
return redirect("/login")
|
||||
|
||||
|
||||
if not account_module.check_account(request.cookies.get("account")):
|
||||
return redirect("/logout")
|
||||
|
||||
domain = domain.lower()
|
||||
response = account_module.revealAuction(request.cookies.get("account"),domain)
|
||||
response = account_module(request.cookies.get("account"),domain)
|
||||
if 'error' in response:
|
||||
return redirect("/auction/" + domain + "?message=" + response['error']['message'])
|
||||
return redirect("/success?tx=" + response['hash'])
|
||||
@@ -1179,7 +1112,8 @@ def settings():
|
||||
# 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}'
|
||||
if info['commit'] != latestVersion(info['refs']):
|
||||
|
||||
if info['commit'] != latestVersion(branch):
|
||||
version += ' (New version available)'
|
||||
return render_template("settings.html", account=account,
|
||||
hsd_version=account_module.hsdVersion(False),
|
||||
@@ -1287,6 +1221,7 @@ def login_post():
|
||||
wallets = account_module.listWallets()
|
||||
wallets = render.wallets(wallets)
|
||||
return render_template("login.html",
|
||||
|
||||
error="Invalid account",wallets=wallets)
|
||||
|
||||
account = account + ":" + password
|
||||
@@ -1565,30 +1500,6 @@ def api_hsd(function):
|
||||
|
||||
return jsonify({"error": "Invalid function", "result": "Invalid function"}), 400
|
||||
|
||||
|
||||
@app.route('/api/v1/hsd/<function>/mobile', methods=["GET"])
|
||||
def api_hsd_mobile(function):
|
||||
# Check if the user is logged in
|
||||
if request.cookies.get("account") is None:
|
||||
return jsonify({"error": "Not logged in"})
|
||||
|
||||
account = account_module.check_account(request.cookies.get("account"))
|
||||
if not account:
|
||||
return jsonify({"error": "Invalid account"})
|
||||
|
||||
if function == "sync":
|
||||
sync = account_module.getNodeSync()
|
||||
if sync == 100:
|
||||
# Don't show sync percentage on mobile
|
||||
sync = ""
|
||||
elif sync == -1:
|
||||
sync = "HSD Error"
|
||||
else:
|
||||
sync = f"{sync}%"
|
||||
return jsonify({"result": sync})
|
||||
|
||||
return jsonify({"error": "Invalid function", "result": "Invalid mobile function"}), 400
|
||||
|
||||
@app.route('/api/v1/wallet/<function>', methods=["GET"])
|
||||
def api_wallet(function):
|
||||
# Check if the user is logged in
|
||||
@@ -1632,56 +1543,8 @@ def api_wallet(function):
|
||||
domains = account_module.getDomains(account)
|
||||
if 'error' in domains:
|
||||
return jsonify({"result": [], "error": domains['error']})
|
||||
|
||||
# Add nameRender to each domain
|
||||
for domain in domains:
|
||||
domain['nameRender'] = renderDomain(domain['name'])
|
||||
|
||||
return jsonify({"result": domains})
|
||||
|
||||
if function == "transactions":
|
||||
# Get the page parameter
|
||||
page = request.args.get('page')
|
||||
try:
|
||||
page = int(page)
|
||||
except:
|
||||
page = 1
|
||||
|
||||
if page < 1:
|
||||
page = 1
|
||||
|
||||
# Check for force refresh parameter
|
||||
force_refresh = request.args.get('refresh') == 'true'
|
||||
|
||||
# Create a cache key based on account and page
|
||||
cache_key = f"{account}_{page}"
|
||||
|
||||
# Check if data is in cache and not expired
|
||||
current_time = time.time()
|
||||
if not force_refresh and cache_key in tx_cache and (current_time - tx_cache[cache_key]['time'] < TX_CACHE_TIMEOUT):
|
||||
transactions = tx_cache[cache_key]['data']
|
||||
txCount = len(transactions)
|
||||
transactions_html = render.transactions(transactions)
|
||||
else:
|
||||
# Fetch transactions from account module
|
||||
transactions = account_module.getTransactions(account, page)
|
||||
txCount = len(transactions)
|
||||
transactions_html = render.transactions(transactions)
|
||||
|
||||
# Store in cache
|
||||
tx_cache[cache_key] = {
|
||||
'data': transactions,
|
||||
'html': transactions_html,
|
||||
'time': current_time
|
||||
}
|
||||
|
||||
return jsonify({
|
||||
"html": transactions_html,
|
||||
"txCount": txCount,
|
||||
"page": page
|
||||
})
|
||||
|
||||
|
||||
if function == "icon":
|
||||
# Check if there is an icon
|
||||
if not os.path.exists(f'user_data/images'):
|
||||
@@ -1693,38 +1556,8 @@ def api_wallet(function):
|
||||
|
||||
return send_file('templates/assets/img/HNS.png')
|
||||
|
||||
|
||||
if function == "possibleOutbids":
|
||||
return jsonify({"result": account_module.getPossibleOutbids(account)})
|
||||
|
||||
|
||||
|
||||
return jsonify({"error": "Invalid function", "result": "Invalid function"}), 400
|
||||
|
||||
@app.route('/api/v1/wallet/<function>/mobile', methods=["GET"])
|
||||
def api_wallet_mobile(function):
|
||||
# Check if the user is logged in
|
||||
if request.cookies.get("account") is None:
|
||||
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"})
|
||||
|
||||
if function == "sync":
|
||||
sync = account_module.getWalletStatus()
|
||||
if sync == "Ready":
|
||||
# Don't show sync percentage on mobile
|
||||
sync = ""
|
||||
elif sync == "Error wallet ahead of node":
|
||||
sync = "HSW Sync Error"
|
||||
else:
|
||||
sync = "HSW Syncing"
|
||||
return jsonify({"result": sync})
|
||||
|
||||
return jsonify({"error": "Invalid function", "result": "Invalid mobile function"}), 400
|
||||
|
||||
@app.route('/api/v1/icon/<account>')
|
||||
def api_icon(account):
|
||||
if not os.path.exists(f'user_data/images'):
|
||||
@@ -1735,35 +1568,6 @@ def api_icon(account):
|
||||
return send_file(f'user_data/images/{file}')
|
||||
return send_file('templates/assets/img/HNS.png')
|
||||
|
||||
|
||||
@app.route('/api/v1/status')
|
||||
def api_status():
|
||||
# This doesn't require a login
|
||||
# Check if the node is connected
|
||||
if not account_module.hsdConnected():
|
||||
return jsonify({"status":503,"error": "Node not connected"}), 503
|
||||
return jsonify({"status": 200,"result": "FireWallet is running"})
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper functions
|
||||
|
||||
def renderDomain(name: str) -> str:
|
||||
"""
|
||||
Render a domain name with emojis and other special characters.
|
||||
"""
|
||||
# Convert emoji to punycode
|
||||
try:
|
||||
rendered = name.encode("ascii").decode("idna")
|
||||
if rendered == name:
|
||||
return f"{name}/"
|
||||
return f"{rendered}/ ({name})"
|
||||
|
||||
|
||||
except Exception as e:
|
||||
return f"{name}/"
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -1790,6 +1594,8 @@ def try_path(path):
|
||||
if not account_module.hsdConnected():
|
||||
return redirect("/login?message=Node not connected")
|
||||
|
||||
|
||||
|
||||
if os.path.isfile("templates/" + path + ".html"):
|
||||
return render_template(path + ".html")
|
||||
else:
|
||||
@@ -1803,9 +1609,8 @@ def page_not_found(e):
|
||||
#endregion
|
||||
|
||||
if __name__ == '__main__':
|
||||
#TODO add parsing to allow for custom port and host
|
||||
# Check to see if --debug is in the command line arguments
|
||||
if "--debug" in sys.argv:
|
||||
app.run(debug=True)
|
||||
app.run(debug=True,host='0.0.0.0')
|
||||
else:
|
||||
app.run()
|
||||
app.run(host='0.0.0.0',threaded=True)
|
||||
63
main.spec
Normal file
63
main.spec
Normal file
@@ -0,0 +1,63 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
import compileall
|
||||
from PyInstaller.utils.hooks import collect_data_files
|
||||
import os
|
||||
|
||||
compileall.compile_dir('.', force=True)
|
||||
|
||||
|
||||
|
||||
datas = [
|
||||
('templates', 'templates'),
|
||||
('assets', 'assets'),
|
||||
('themes', 'themes'),
|
||||
('plugins', 'plugins')
|
||||
]
|
||||
hiddenimports = [
|
||||
'plugins.automations',
|
||||
'plugins.batching',
|
||||
'plugins.customPlugins',
|
||||
'plugins.renewal',
|
||||
'plugins.varo'
|
||||
]
|
||||
|
||||
# Copy the plugins folder to the dist folder
|
||||
os.system(f'cp -r plugins dist/')
|
||||
|
||||
a = Analysis(
|
||||
['main.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=datas,
|
||||
hiddenimports=hiddenimports,
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='FireWallet',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
onefile=False,
|
||||
)
|
||||
@@ -9,7 +9,7 @@ import os
|
||||
info = {
|
||||
"name": "Batching Functions",
|
||||
"description": "This is a plugin that provides multiple functions to batch transactions",
|
||||
"version": "1.1",
|
||||
"version": "1.0",
|
||||
"author": "Nathan.Woodburn/"
|
||||
}
|
||||
# https://hsd-dev.org/api-docs/?shell--cli#sendbatch
|
||||
@@ -394,6 +394,7 @@ def bid(params, authentication):
|
||||
for domain in domains:
|
||||
batch.append(['BID', domain, bid, blind])
|
||||
|
||||
print(batch)
|
||||
response = sendBatch(batch, authentication)
|
||||
if 'error' in response:
|
||||
return {
|
||||
|
||||
324
render.py
324
render.py
@@ -4,46 +4,13 @@ import urllib.parse
|
||||
from flask import render_template
|
||||
from domainLookup import punycode_to_emoji
|
||||
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_NETWORK = os.getenv("HSD_NETWORK")
|
||||
HSD_WALLET_PORT = 12039
|
||||
HSD_NODE_PORT = 12037
|
||||
|
||||
if not HSD_NETWORK:
|
||||
HSD_NETWORK = "main"
|
||||
else:
|
||||
HSD_NETWORK = HSD_NETWORK.lower()
|
||||
|
||||
if HSD_NETWORK == "simnet":
|
||||
HSD_WALLET_PORT = 15039
|
||||
HSD_NODE_PORT = 15037
|
||||
elif HSD_NETWORK == "testnet":
|
||||
HSD_WALLET_PORT = 13039
|
||||
HSD_NODE_PORT = 13037
|
||||
elif HSD_NETWORK == "regtest":
|
||||
HSD_WALLET_PORT = 14039
|
||||
HSD_NODE_PORT = 14037
|
||||
|
||||
hsd = api.hsd(HSD_API, HSD_IP, HSD_NODE_PORT)
|
||||
|
||||
# Get Explorer URL
|
||||
TX_EXPLORER_URL = os.getenv("EXPLORER_TX")
|
||||
if TX_EXPLORER_URL is None:
|
||||
TX_EXPLORER_URL = "https://shakeshift.com/transaction/"
|
||||
TX_EXPLORER_URL = "https://niami.io/tx/"
|
||||
|
||||
|
||||
NAMEHASH_CACHE = 'user_data/namehash_cache.json'
|
||||
CACHE_LOCK = threading.Lock()
|
||||
|
||||
|
||||
HNS_ICON = '<img src="/assets/img/HNS.png" width="20px" style="filter: invert(1);" />'
|
||||
|
||||
def domains(domains, mobile=False):
|
||||
html = ''
|
||||
@@ -57,7 +24,10 @@ def domains(domains, mobile=False):
|
||||
paid = paid / 1000000
|
||||
|
||||
# Handle punycodes
|
||||
name = renderDomain(domain['name'])
|
||||
name = domain['name']
|
||||
emoji = punycode_to_emoji(name)
|
||||
if emoji != name:
|
||||
name = f'{emoji} ({name})'
|
||||
|
||||
|
||||
link = f'/manage/{domain["name"]}'
|
||||
@@ -73,29 +43,6 @@ def domains(domains, mobile=False):
|
||||
|
||||
return html
|
||||
|
||||
|
||||
actionMap = {
|
||||
"UPDATE": "Updated ",
|
||||
"REGISTER": "Registered ",
|
||||
"RENEW": "Renewed ",
|
||||
"BID": "Bid on ",
|
||||
"REVEAL": "Revealed bid for ",
|
||||
"REDEEM": "Redeemed bid for ",
|
||||
"TRANSFER": "Started transfer for ",
|
||||
"NONE": "Multiple actions"
|
||||
}
|
||||
|
||||
actionMapPlural = {
|
||||
"UPDATE": "Updated multiple domains' records",
|
||||
"REGISTER": "Registered multiple domains",
|
||||
"RENEW": "Renewed multiple domains",
|
||||
"BID": "Bid on multiple domains",
|
||||
"REVEAL": "Revealed multiple bids",
|
||||
"REDEEM": "Redeemed multiple bids",
|
||||
"TRANSFER": "Started multiple domain transfers",
|
||||
"NONE": "Multiple actions"
|
||||
}
|
||||
|
||||
def transactions(txs):
|
||||
|
||||
if len(txs) == 0:
|
||||
@@ -103,106 +50,38 @@ def transactions(txs):
|
||||
html = ''
|
||||
for tx in txs:
|
||||
action = "HNS Transfer"
|
||||
txhash = tx["hash"]
|
||||
address = tx["outputs"][0]["address"]
|
||||
hash = tx["hash"]
|
||||
confirmations=tx["confirmations"]
|
||||
mined_date = "Pending"
|
||||
if confirmations >= 1:
|
||||
mined_date = tx["mdate"]
|
||||
if mined_date is None:
|
||||
mined_date = "Pending"
|
||||
else:
|
||||
# Format 2025-06-27T01:49:14Z
|
||||
mined_date = datetime.datetime.strptime(mined_date, "%Y-%m-%dT%H:%M:%SZ").strftime("%d %b %Y")
|
||||
incomming = True
|
||||
amount = 0
|
||||
bid_value = 0
|
||||
isMulti = 0
|
||||
nameHashes = []
|
||||
|
||||
for txInput in tx["inputs"]:
|
||||
if txInput["path"]:
|
||||
incomming = False
|
||||
amount -= txInput["value"]
|
||||
if not tx["inputs"][0]["path"]:
|
||||
incomming = True
|
||||
|
||||
for output in tx["outputs"]:
|
||||
if output["covenant"]["action"] != "NONE":
|
||||
if action == "HNS Transfer":
|
||||
action = output["covenant"]["action"]
|
||||
elif action == output["covenant"]["action"]:
|
||||
isMulti += 1
|
||||
continue
|
||||
else:
|
||||
action = "Multiple Actions"
|
||||
|
||||
|
||||
if output["covenant"]["items"] and len(output["covenant"]["items"]) > 0:
|
||||
nameHashes.append(output["covenant"]["items"][0])
|
||||
|
||||
if not incomming:
|
||||
if output["path"]:
|
||||
if not output["path"] and not incomming:
|
||||
amount += output["value"]
|
||||
else:
|
||||
if output["path"] and output["covenant"]["action"] == "NONE":
|
||||
elif output["path"] and incomming:
|
||||
amount += output["value"]
|
||||
|
||||
# Check if this is a bid
|
||||
if output["covenant"]["action"] == "BID":
|
||||
bid_value += output["value"]
|
||||
amount -= output["value"]
|
||||
|
||||
if not incomming:
|
||||
# Subtract fee to make it easier to read
|
||||
amount += tx["fee"]
|
||||
|
||||
|
||||
amount = amount / 1000000
|
||||
bid_value = bid_value / 1000000
|
||||
humanAction = action
|
||||
|
||||
if action == "HNS Transfer":
|
||||
if amount >= 0:
|
||||
humanAction = f"Received {amount:,.2f} {HNS_ICON}"
|
||||
else:
|
||||
humanAction = f"Sent {(amount*-1):,.2f} {HNS_ICON}"
|
||||
elif action == "FINALIZE":
|
||||
if incomming and not isMulti:
|
||||
humanAction = f"Received {renderFromNameHash(nameHashes[0])}"
|
||||
elif incomming and isMulti:
|
||||
humanAction = f"Received {isMulti + 1} domains"
|
||||
elif not isMulti:
|
||||
humanAction = f"Finalized {renderFromNameHash(nameHashes[0])}"
|
||||
else:
|
||||
humanAction = f"Finalized {isMulti + 1} domain transfers"
|
||||
elif action == "BID" and not isMulti:
|
||||
humanAction = f"Bid {bid_value:,.2f} {HNS_ICON} on {renderFromNameHash(nameHashes[0])}"
|
||||
elif isMulti:
|
||||
humanAction = actionMapPlural.get(action, "Unknown Action")
|
||||
humanAction = humanAction.replace("multiple", f'{isMulti + 1}')
|
||||
else:
|
||||
humanAction = actionMap.get(action, "Unknown Action")
|
||||
humanAction += renderFromNameHash(nameHashes[0])
|
||||
|
||||
|
||||
if amount < 0:
|
||||
amount = f"<span style='color: red;'>{amount:,.2f}</span>"
|
||||
elif amount > 0:
|
||||
amount = f"<span style='color: green;'>+{amount:,.2f}</span>"
|
||||
else:
|
||||
amount = f"<span style='color: gray;'>0.00</span>"
|
||||
|
||||
|
||||
# hash = f"<a target='_blank' href='{TX_EXPLORER_URL}{hash}'>{hash[:8]}...</a>"
|
||||
txdate = ""
|
||||
hash = f"<a target='_blank' href='{TX_EXPLORER_URL}{hash}'>{hash[:8]}...</a>"
|
||||
if confirmations < 5:
|
||||
txdate = f"<span style='color: red;'>{mined_date}</span>"
|
||||
confirmations = f"<td style='background-color: red;'>{confirmations}</td>"
|
||||
else:
|
||||
txdate = f"<span>{mined_date}</span>"
|
||||
# confirmations = f"<td class='hide-mobile'>{confirmations:,}</td>"
|
||||
html += f'''
|
||||
<tr>
|
||||
<td style='white-space: nowrap;'>{txdate}</td>
|
||||
<td><a style="color:var(--bs-body-color); text-decoration:none;" target="_blank" href="{TX_EXPLORER_URL}{txhash}">{humanAction}</a></td>
|
||||
</tr>
|
||||
'''
|
||||
confirmations = f"<td>{confirmations:,}</td>"
|
||||
|
||||
|
||||
html += f'<tr><td>{action}</td><td>{address}</td><td>{hash}</td>{confirmations}<td>{amount:,.2f} HNS</td></tr>'
|
||||
return html
|
||||
|
||||
|
||||
@@ -216,28 +95,28 @@ def dns(data, edit=False):
|
||||
for key, value in entry.items():
|
||||
if key != 'type':
|
||||
if isinstance(value, list):
|
||||
if len(value) > 1:
|
||||
html_output += '<td style="white-space: pre-wrap; font-family: monospace;">\n'
|
||||
html_output += "<td>\n"
|
||||
for val in value:
|
||||
html_output += f"{val}<br>\n"
|
||||
|
||||
html_output += "</td>\n"
|
||||
else:
|
||||
html_output += f'<td style="white-space: pre-wrap; font-family: monospace;">{value[0]}</td>\n'
|
||||
else:
|
||||
html_output += f'<td style="white-space: pre-wrap; font-family: monospace;">{value}</td>\n'
|
||||
html_output += f"<td>{value}</td>\n"
|
||||
|
||||
|
||||
elif entry['type'] == 'DS':
|
||||
ds = f"{entry['keyTag']} {entry['algorithm']} {entry['digestType']} {entry['digest']}"
|
||||
html_output += f'<td style="white-space: pre-wrap; font-family: monospace;">{ds}</td>\n'
|
||||
html_output += f"<td>{ds}</td>\n"
|
||||
|
||||
else:
|
||||
value = ""
|
||||
for key, val in entry.items():
|
||||
if key != 'type':
|
||||
value += f'{val} '
|
||||
html_output += f'<td style="white-space: pre-wrap; font-family: monospace;">{value.strip()}</td>\n'
|
||||
html_output += f"<td>{value}</td>\n"
|
||||
|
||||
if edit:
|
||||
# Remove the current entry from the list
|
||||
keptRecords = str(data[:index] + data[index+1:]).replace("'", '"')
|
||||
keptRecords = urllib.parse.quote(keptRecords)
|
||||
html_output += f"<td><a href='edit?dns={keptRecords}'>Remove</a></td>\n"
|
||||
@@ -246,7 +125,6 @@ def dns(data, edit=False):
|
||||
index += 1
|
||||
return html_output
|
||||
|
||||
|
||||
def txs(data):
|
||||
data = data[::-1]
|
||||
|
||||
@@ -278,66 +156,36 @@ def timestamp_to_readable_time(timestamp):
|
||||
return readable_time
|
||||
|
||||
def bids(bids,reveals):
|
||||
# Create a list to hold bid data for sorting
|
||||
bid_data = []
|
||||
|
||||
# Prepare data for sorting
|
||||
html = ''
|
||||
for bid in bids:
|
||||
lockup = bid['lockup'] / 1000000
|
||||
lockup = bid['lockup']
|
||||
lockup = lockup / 1000000
|
||||
html += "<tr>"
|
||||
html += f"<td>{lockup:,.2f} HNS</td>"
|
||||
revealed = False
|
||||
value = 0
|
||||
|
||||
# Check if this bid has been revealed
|
||||
for reveal in reveals:
|
||||
if reveal['bid'] == bid['prevout']['hash']:
|
||||
revealed = True
|
||||
value = reveal['value'] / 1000000
|
||||
break
|
||||
|
||||
# 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
|
||||
value = reveal['value']
|
||||
value = value / 1000000
|
||||
html += f"<td>{value:,.2f} HNS</td>"
|
||||
bidValue = lockup - value
|
||||
html += f"<td>{bidValue:,.2f} HNS</td>"
|
||||
else:
|
||||
break
|
||||
if not revealed:
|
||||
html += f"<td>Hidden until reveal</td>"
|
||||
html += f"<td>Hidden until reveal</td>"
|
||||
|
||||
if bid['own']:
|
||||
html += "<td>You</td>"
|
||||
else:
|
||||
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 += "<td>Unknown</td>"
|
||||
html += "</tr>"
|
||||
|
||||
return html
|
||||
|
||||
|
||||
def bidDomains(bids,domains, sortbyDomains=False, outbids=[]):
|
||||
def bidDomains(bids,domains, sortbyDomains=False):
|
||||
html = ''
|
||||
|
||||
if not sortbyDomains:
|
||||
for bid in bids:
|
||||
for domain in domains:
|
||||
@@ -347,19 +195,14 @@ def bidDomains(bids,domains, sortbyDomains=False, outbids=[]):
|
||||
bidValue = bid['value'] / 1000000
|
||||
blind = lockup - bidValue
|
||||
|
||||
if blind > 0:
|
||||
bidDisplay = f'<b>{bidValue:,.2f}</b> (+{blind:,.2f}) HNS'
|
||||
else:
|
||||
bidDisplay = f'<b>{bidValue:,.2f}</b> HNS'
|
||||
bidDisplay = f'<b>{bidValue:,.2f} HNS</b> + {blind:,.2f} HNS blind'
|
||||
|
||||
|
||||
html += "<tr>"
|
||||
if domain['name'] in outbids:
|
||||
html += f"<td style='background-color: red;'><a class='text-decoration-none' style='color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));' href='/auction/{domain['name']}'>{renderDomain(domain['name'])}</a></td>"
|
||||
else:
|
||||
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='/auction/{domain['name']}'>{renderDomain(domain['name'])}</a></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='/auction/{domain['name']}'>{domain['name']}</a></td>"
|
||||
html += f"<td>{domain['state']}</td>"
|
||||
html += f"<td style='white-space: nowrap;'>{bidDisplay}</td>"
|
||||
html += f"<td class='hide-mobile'>{bid['height']:,}</td>"
|
||||
html += f"<td>{bidDisplay}</td>"
|
||||
html += f"<td>{domain['height']:,}</td>"
|
||||
html += "</tr>"
|
||||
else:
|
||||
for domain in domains:
|
||||
@@ -372,10 +215,10 @@ def bidDomains(bids,domains, sortbyDomains=False, outbids=[]):
|
||||
|
||||
bidDisplay = f'<b>{bidValue:,.2f} HNS</b> + {blind:,.2f} HNS blind'
|
||||
html += "<tr>"
|
||||
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='/auction/{domain['name']}'>{renderDomain(domain['name'])}</a></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='/auction/{domain['name']}'>{domain['name']}</a></td>"
|
||||
html += f"<td>{domain['state']}</td>"
|
||||
html += f"<td>{bidDisplay}</td>"
|
||||
html += f"<td class='hide-mobile'>{bid['height']:,}</td>"
|
||||
html += f"<td>{domain['height']:,}</td>"
|
||||
html += "</tr>"
|
||||
return html
|
||||
|
||||
@@ -509,80 +352,3 @@ def plugin_output_dash(outputs, returns):
|
||||
continue
|
||||
html += render_template('components/dashboard-plugin.html', name=returns[returnOutput]["name"], output=outputs[returnOutput])
|
||||
return html
|
||||
|
||||
|
||||
|
||||
def renderDomain(name: str) -> str:
|
||||
"""
|
||||
Render a domain name with emojis and other special characters.
|
||||
"""
|
||||
# Convert emoji to punycode
|
||||
try:
|
||||
rendered = name.encode("ascii").decode("idna")
|
||||
if rendered == name:
|
||||
return f"{name}/"
|
||||
return f"{rendered}/ ({name})"
|
||||
|
||||
|
||||
except Exception as e:
|
||||
return f"{name}/"
|
||||
|
||||
def renderDomainAsync(namehash: str) -> None:
|
||||
"""
|
||||
Get the domain name from HSD using its name hash and store it in the cache.
|
||||
This function is meant to be run in the background.
|
||||
"""
|
||||
try:
|
||||
with CACHE_LOCK:
|
||||
if not os.path.exists(NAMEHASH_CACHE):
|
||||
with open(NAMEHASH_CACHE, 'w') as f:
|
||||
json.dump({}, f)
|
||||
with open(NAMEHASH_CACHE, 'r') as f:
|
||||
cache = json.load(f)
|
||||
|
||||
if namehash in cache:
|
||||
return
|
||||
|
||||
# Fetch the name outside the lock (network call)
|
||||
name = hsd.rpc_getNameByHash(namehash)
|
||||
if name["error"] is None:
|
||||
name = name["result"]
|
||||
rendered = renderDomain(name)
|
||||
|
||||
with CACHE_LOCK:
|
||||
with open(NAMEHASH_CACHE, 'r') as f:
|
||||
cache = json.load(f)
|
||||
cache[namehash] = rendered
|
||||
with open(NAMEHASH_CACHE, 'w') as f:
|
||||
json.dump(cache, f)
|
||||
|
||||
return rendered
|
||||
else:
|
||||
print(f"Error fetching name for hash {namehash}: {name['error']}", flush=True)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Exception fetching name for hash {namehash}: {e}", flush=True)
|
||||
|
||||
|
||||
def renderFromNameHash(nameHash: str) -> str:
|
||||
"""
|
||||
Render a domain name from its name hash.
|
||||
Try to retrieve the name from the cache. If not, create a background task to fetch it.
|
||||
"""
|
||||
try:
|
||||
with CACHE_LOCK:
|
||||
if not os.path.exists(NAMEHASH_CACHE):
|
||||
with open(NAMEHASH_CACHE, 'w') as f:
|
||||
json.dump({}, f)
|
||||
with open(NAMEHASH_CACHE, 'r') as f:
|
||||
cache = json.load(f)
|
||||
|
||||
if nameHash in cache:
|
||||
return cache[nameHash]
|
||||
thread = threading.Thread(target=renderDomainAsync, args=(nameHash,))
|
||||
thread.start()
|
||||
return "domain"
|
||||
|
||||
except Exception as e:
|
||||
print(f"Exception in renderFromNameHash: {e}", flush=True)
|
||||
return "domain"
|
||||
@@ -9,4 +9,3 @@ requests-doh
|
||||
Flask-QRcode
|
||||
PySocks
|
||||
python-git-info
|
||||
waitress
|
||||
40
server.py
40
server.py
@@ -1,14 +1,10 @@
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
from flask import Flask
|
||||
from main import app
|
||||
from waitress import serve
|
||||
|
||||
|
||||
threads = 4
|
||||
|
||||
def gunicornServer():
|
||||
import main
|
||||
from gunicorn.app.base import BaseApplication
|
||||
import os
|
||||
|
||||
|
||||
class GunicornApp(BaseApplication):
|
||||
def __init__(self, app, options=None):
|
||||
self.options = options or {}
|
||||
@@ -22,23 +18,21 @@ def gunicornServer():
|
||||
|
||||
def load(self):
|
||||
return self.application
|
||||
|
||||
if __name__ == '__main__':
|
||||
workers = 1
|
||||
threads = 2
|
||||
if workers is None:
|
||||
workers = 1
|
||||
if threads is None:
|
||||
threads = 2
|
||||
workers = int(workers)
|
||||
threads = int(threads)
|
||||
options = {
|
||||
'bind': '0.0.0.0:5000',
|
||||
'workers': 2,
|
||||
'workers': workers,
|
||||
'threads': threads,
|
||||
}
|
||||
gunicorn_app = GunicornApp(app, options)
|
||||
print(f'Starting server with Gunicorn on {platform.system()} with {threads} threads...', flush=True)
|
||||
print('Starting server with ' + str(workers) + ' workers and ' + str(threads) + ' threads', flush=True)
|
||||
gunicorn_app.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Check if --gunicorn is in the command line arguments
|
||||
if "--gunicorn" in sys.argv:
|
||||
gunicornServer()
|
||||
sys.exit()
|
||||
|
||||
print(f'Starting server with Waitress on {platform.system()} with {threads} threads...', flush=True)
|
||||
print(f'Press Ctrl+C to stop the server', flush=True)
|
||||
print(f'Serving on http://0.0.0.0:5000/', flush=True)
|
||||
serve(app, host="0.0.0.0", port=5000, threads=threads)
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -64,7 +64,7 @@
|
||||
</nav>
|
||||
<div class="container-fluid">
|
||||
<div class="text-center mt-5">
|
||||
<div class="mx-auto error" data-text="404">
|
||||
<div class="error mx-auto" data-text="404">
|
||||
<p class="m-0">404</p>
|
||||
</div>
|
||||
<p class="text-dark mb-5 lead">Page Not Found</p>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
templates/assets/js/dashboard.min.js
vendored
2
templates/assets/js/dashboard.min.js
vendored
@@ -1 +1 @@
|
||||
function createCard(e,n,t){if(document.getElementById(t)&&document.getElementById(t).remove(),n<=0)return;const s=document.createElement("div");s.classList.add("col-md-6","col-xl-3","mb-4"),s.id=t,html=`\n <div class="card shadow border-start-warning py-2">\n <div class="card-body">\n <div class="row align-items-center no-gutters">\n <div class="col me-2">\n <div class="text-uppercase text-warning fw-bold text-xs mb-1"><span>${e}</span></div>\n <div class="text-dark fw-bold h5 mb-0"><span id="${e}">${n}</span></div>\n </div>\n <div class="col"><a class="btn btn-primary" role="button" href="/all/${t.toLowerCase()}">${t} All</a></div>\n <div class="col-auto"><svg class="fa-2x text-gray-300" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor">\n <g>\n <rect fill="none" height="24" width="24"></rect>\n </g>\n <g>\n <path d="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M7,13.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C8.5,12.83,7.83,13.5,7,13.5z M12,13.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C13.5,12.83,12.83,13.5,12,13.5z M17,13.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C18.5,12.83,17.83,13.5,17,13.5z"></path>\n </g>\n </svg></div>\n </div>\n </div>`,s.innerHTML=html,document.getElementById("actions-row").appendChild(s)}async function updateActions(){const e={Finalize:"Pending Finalizes",Register:"Pending Register",Redeem:"Pending Redeem",Reveal:"Pending Reveal"},n=Object.keys(e).map((e=>request(`wallet/pending${e}`).then((n=>({id:e,result:n}))))),t=await Promise.all(n);for(const{id:n,result:s}of t)"Error"!==s&&createCard(e[n],s.length,n);const s=await request("wallet/possibleOutbids");if("Error"===s)return;const d=document.getElementById("outbids");if(d&&d.remove(),s.length<=0)return;const i=document.createElement("div");i.classList.add("col-md-6","col-xl-3","mb-4"),i.id="outbids",i.innerHTML=`\n <div class="card shadow border-start-warning py-2">\n <div class="card-body">\n <div class="row align-items-center no-gutters">\n <div class="col me-2">\n <div class="text-uppercase text-warning fw-bold text-xs mb-1"><span>Names with possible outbids</span></div>\n <div class="text-dark fw-bold h5 mb-0"><span id="outbids-count">${s.length}</span></div>\n </div>\n <div class="col"><a class="btn btn-primary" role="button" href="/auctions?outbids=true">Show All</a></div>\n <div class="col-auto">\n <svg class="fa-2x text-gray-300" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor">\n <g><rect fill="none" height="24" width="24"></rect></g>\n <g>\n <path d="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M7,13.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C8.5,12.83,7.83,13.5,7,13.5z M12,13.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C13.5,12.83,12.83,13.5,12,13.5z M17,13.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C18.5,12.83,17.83,13.5,17,13.5z"></path>\n </g>\n </svg>\n </div>\n </div>\n </div>\n </div>\n `,document.getElementById("actions-row").appendChild(i)}window.addEventListener("load",(async()=>{updateActions()})),setInterval((async function(){updateActions()}),2e4);
|
||||
function createCard(e,n,t){if(document.getElementById(t)&&document.getElementById(t).remove(),n<=0)return;const a=document.createElement("div");a.classList.add("col-md-6","col-xl-3","mb-4"),a.id=t,html=`\n <div class="card shadow border-start-warning py-2">\n <div class="card-body">\n <div class="row align-items-center no-gutters">\n <div class="col me-2">\n <div class="text-uppercase text-warning fw-bold text-xs mb-1"><span>${e}</span></div>\n <div class="text-dark fw-bold h5 mb-0"><span id="${e}">${n}</span></div>\n </div>\n <div class="col"><a class="btn btn-primary" role="button" href="/all/${t.toLowerCase()}">${t} All</a></div>\n <div class="col-auto"><svg class="fa-2x text-gray-300" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor">\n <g>\n <rect fill="none" height="24" width="24"></rect>\n </g>\n <g>\n <path d="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M7,13.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C8.5,12.83,7.83,13.5,7,13.5z M12,13.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C13.5,12.83,12.83,13.5,12,13.5z M17,13.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C18.5,12.83,17.83,13.5,17,13.5z"></path>\n </g>\n </svg></div>\n </div>\n </div>`,a.innerHTML=html,document.getElementById("actions-row").appendChild(a)}async function updateActions(){const e={Finalize:"Pending Finalizes",Register:"Pending Register",Redeem:"Pending Redeem",Reveal:"Pending Reveal"};for(const n in e){const t=await request(`wallet/pending${n}`);"Error"!=t&&createCard(e[n],t.length,n)}}window.addEventListener("load",(async()=>{updateActions()})),setInterval((async function(){updateActions()}),2e4);
|
||||
2
templates/assets/js/script.min.js
vendored
2
templates/assets/js/script.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -67,8 +67,8 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="stick-right">{{next_action|safe}}</div>
|
||||
<h4 class="card-title">{{rendered}}</h4>
|
||||
<h6 class="text-muted mb-2 card-subtitle">{{next | safe}}</h6>
|
||||
<h4 class="card-title">{{domain}}/</h4>
|
||||
<h6 class="text-muted card-subtitle mb-2">{{next}}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -93,7 +93,6 @@
|
||||
<th>Bid</th>
|
||||
<th>Blind</th>
|
||||
<th>Owner</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -69,12 +69,12 @@
|
||||
<h1 class="text-center">{{message}}</h1>
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-xl-3 mb-4">
|
||||
<div class="card shadow py-2 border-start-primary">
|
||||
<div class="card shadow border-start-primary py-2">
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center no-gutters">
|
||||
<div class="col me-2">
|
||||
<div class="text-uppercase text-primary mb-1 fw-bold text-xs"><span style="color: var(--bs-dark);">HNS Locked</span></div>
|
||||
<div class="text-dark mb-0 fw-bold h5"><span><img src="/assets/img/HNS.png" width="20px"> <span id="wallet-locked">0.00</span></span></div>
|
||||
<div class="text-uppercase text-primary fw-bold text-xs mb-1"><span style="color: var(--bs-dark);">HNS Locked</span></div>
|
||||
<div class="text-dark fw-bold h5 mb-0"><span><img src="/assets/img/HNS.png" width="20px"> <span id="wallet-locked">0.00</span></span></div>
|
||||
</div>
|
||||
<div class="col-auto"><i class="fas fa-dollar-sign fa-2x text-gray-300"></i></div>
|
||||
</div>
|
||||
@@ -82,26 +82,26 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-3 mb-4">
|
||||
<div class="card shadow py-2 border-start-success">
|
||||
<div class="card shadow border-start-success py-2">
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center no-gutters">
|
||||
<div class="col me-2">
|
||||
<div class="text-uppercase text-success mb-1 fw-bold text-xs"><span>Total Bids</span></div>
|
||||
<div class="text-dark mb-0 fw-bold h5"><span id="wallet-bidCount">0</span></div>
|
||||
<div class="text-uppercase text-success fw-bold text-xs mb-1"><span>Total Bids</span></div>
|
||||
<div class="text-dark fw-bold h5 mb-0"><span id="wallet-bidCount">0</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-3 mb-4">
|
||||
<div class="card shadow py-2 border-start-info">
|
||||
<div class="card shadow border-start-info py-2">
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center no-gutters">
|
||||
<div class="col me-2">
|
||||
<div class="text-uppercase text-info mb-1 fw-bold text-xs"><span>Pending Reveal</span></div>
|
||||
<div class="text-uppercase text-info fw-bold text-xs mb-1"><span>Pending Reveal</span></div>
|
||||
<div class="row g-0 align-items-center">
|
||||
<div class="col-auto">
|
||||
<div class="text-dark me-3 mb-0 fw-bold h5"><span id="wallet-pendingReveal">0</span></div>
|
||||
<div class="text-dark fw-bold h5 mb-0 me-3"><span id="wallet-pendingReveal">0</span></div>
|
||||
</div>
|
||||
<div class="col"><a class="btn btn-primary" role="button" href="/all/reveal">Reveal All</a></div>
|
||||
</div>
|
||||
@@ -111,14 +111,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-3 mb-4">
|
||||
<div class="card shadow py-2 border-start-info">
|
||||
<div class="card shadow border-start-info py-2">
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center no-gutters">
|
||||
<div class="col me-2">
|
||||
<div class="text-uppercase text-info mb-1 fw-bold text-xs"><span>Pending Redeem</span></div>
|
||||
<div class="text-uppercase text-info fw-bold text-xs mb-1"><span>Pending Redeem</span></div>
|
||||
<div class="row g-0 align-items-center">
|
||||
<div class="col-auto">
|
||||
<div class="text-dark me-3 mb-0 fw-bold h5"><span id="wallet-pendingRedeem">0</span></div>
|
||||
<div class="text-dark fw-bold h5 mb-0 me-3"><span id="wallet-pendingRedeem">0</span></div>
|
||||
</div>
|
||||
<div class="col"><a class="btn btn-primary" role="button" href="/all/redeem">Redeem All</a></div>
|
||||
</div>
|
||||
@@ -128,14 +128,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-3 mb-4">
|
||||
<div class="card shadow py-2 border-start-info">
|
||||
<div class="card shadow border-start-info py-2">
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center no-gutters">
|
||||
<div class="col me-2">
|
||||
<div class="text-uppercase text-info mb-1 fw-bold text-xs"><span>Pending Register</span></div>
|
||||
<div class="text-uppercase text-info fw-bold text-xs mb-1"><span>Pending Register</span></div>
|
||||
<div class="row g-0 align-items-center">
|
||||
<div class="col-auto">
|
||||
<div class="text-dark me-3 mb-0 fw-bold h5"><span id="wallet-pendingRegister">0</span></div>
|
||||
<div class="text-dark fw-bold h5 mb-0 me-3"><span id="wallet-pendingRegister">0</span></div>
|
||||
</div>
|
||||
<div class="col"><a class="btn btn-primary" role="button" href="/all/register">Register All</a></div>
|
||||
</div>
|
||||
@@ -145,11 +145,11 @@
|
||||
</div>
|
||||
</div>{{plugins|safe}}
|
||||
</div>
|
||||
<div class="row d-none d-print-block d-sm-none d-md-none d-lg-block d-xl-block d-xxl-block">
|
||||
<div class="row d-none d-sm-none d-md-block">
|
||||
<div class="col">
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h6 class="text-primary m-0 fw-bold">Domains</h6>
|
||||
<h6 class="text-primary fw-bold m-0">Domains</h6>
|
||||
</div>
|
||||
<div class="card-body"><div class="table-responsive">
|
||||
<table class="table">
|
||||
@@ -170,11 +170,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row d-block d-print-none d-sm-block d-md-block d-lg-none d-xl-none d-xxl-none">
|
||||
<div class="row d-block d-sm-block d-md-none">
|
||||
<div class="col">
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h6 class="text-primary m-0 fw-bold">Domains</h6>
|
||||
<h6 class="text-primary fw-bold m-0">Domains</h6>
|
||||
</div>
|
||||
<div class="card-body"><div class="table-responsive">
|
||||
<table class="table">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<span style="display: block;font-size: 12px;">TX: {{tx}}</span>
|
||||
<span style="display: block;">Check your transaction on a block explorer</span>
|
||||
<a class="card-link" href="https://shakeshift.com/transaction/{{tx}}" target="_blank">ShakeShift</a>
|
||||
<a class="card-link" href="https://niami.io/tx/{{tx}}" target="_blank">Niami</a>
|
||||
<a class="card-link" href="https://3xpl.com/handshake/transaction/{{tx}}" target="_blank">3xpl</a>
|
||||
<a class="card-link" href="https://hns.cymon.de/tx/{{tx}}" target="_blank">Cymon.de</a>
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -67,7 +67,7 @@
|
||||
<div class="card" style="margin-top: 50px;">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">{{action}}</h4>
|
||||
<h6 class="text-muted mb-2 card-subtitle">{{subtitle}}</h6>
|
||||
<h6 class="text-muted card-subtitle mb-2">{{subtitle}}</h6>
|
||||
<p class="card-text">{{content|safe}}</p>
|
||||
<form method="post" action="{{confirm}}"><input class="form-control" type="password" name="password" placeholder="Password"><input class="btn btn-primary" type="submit" style="display: block;margin-top: 16px;margin-bottom: 16px;"><input class="form-control" type="hidden" name="check" value="{{check}}"></form><a class="card-link" href="{{cancel}}">Cancel</a>
|
||||
</div>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -67,7 +67,7 @@
|
||||
<div class="card" style="margin-top: 50px;">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">{{action}}</h4>
|
||||
<h6 class="text-muted mb-2 card-subtitle">{{subtitle}}</h6>
|
||||
<h6 class="text-muted card-subtitle mb-2">{{subtitle}}</h6>
|
||||
<p class="card-text">{{content|safe}}</p><a class="card-link" href="{{cancel}}">Cancel</a><a class="card-link" href="{{confirm}}">Confirm</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span>Sync: {{sync}}%</span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ...">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small">{{account}}</span><img class="border rounded-circle img-profile" src="/assets/img/HNS.png"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -66,7 +66,7 @@
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">{{rendered}}</h4>
|
||||
<h4 class="card-title">{{domain}}/</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<body class="bg-gradient-primary">
|
||||
<div class="container">
|
||||
<div class="card shadow-lg my-5 o-hidden border-0">
|
||||
<div class="card shadow-lg o-hidden border-0 my-5">
|
||||
<div class="card-body p-0">
|
||||
<div class="row">
|
||||
<div class="col-lg-5 d-none d-lg-flex">
|
||||
@@ -30,12 +30,12 @@
|
||||
<h4 class="text-dark mb-4">Import a wallet!</h4>
|
||||
</div>
|
||||
<form class="user" method="post">
|
||||
<div class="mb-3 row" style="padding-right: 16px;padding-left: 16px;"><input class="form-control form-control-user" type="text" id="exampleLastName" placeholder="Wallet name" name="name" value="{{name}}"></div>
|
||||
<div class="mb-3 row">
|
||||
<div class="row mb-3" style="padding-right: 16px;padding-left: 16px;"><input class="form-control form-control-user" type="text" id="exampleLastName" placeholder="Wallet name" name="name" value="{{name}}"></div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-6 mb-3 mb-sm-0"><input class="form-control form-control-user" type="password" id="examplePasswordInput" placeholder="Password" name="password" required="" value="{{password}}"></div>
|
||||
<div class="col-sm-6"><input class="form-control form-control-user" type="password" id="exampleRepeatPasswordInput" placeholder="Repeat Password" name="password_repeat" required="" value="{{password_repeat}}"></div>
|
||||
</div>
|
||||
<div style="margin-bottom: 16px;"><textarea class="form-control form-control-lg" placeholder="Seed Phrase" name="seed" rows="1" style="height: 7em;">{{seed}}</textarea></div><button class="btn btn-primary d-block w-100 btn-user" type="submit">Import Wallet</button>
|
||||
<div style="margin-bottom: 16px;"><textarea class="form-control form-control-lg" placeholder="Seed Phrase" name="seed" rows="1" style="height: 7em;">{{seed}}</textarea></div><button class="btn btn-primary d-block btn-user w-100" type="submit">Import Wallet</button>
|
||||
<hr>
|
||||
</form>
|
||||
<div class="text-center"><a class="small" href="/login">Didn't mean to create a new wallet? Login!</a></div>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link active" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -68,12 +68,12 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-xl-3 mb-4">
|
||||
<div class="card shadow py-2 border-start-primary">
|
||||
<div class="card shadow border-start-primary py-2">
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center no-gutters">
|
||||
<div class="col me-2">
|
||||
<div class="text-uppercase text-primary mb-1 fw-bold text-xs"><span style="color: var(--bs-dark);">HNS Available</span></div>
|
||||
<div class="text-dark mb-0 fw-bold h5"><span><img src="/assets/img/HNS.png" width="20px"> <span id="wallet-available">0.00</span></span></div>
|
||||
<div class="text-uppercase text-primary fw-bold text-xs mb-1"><span style="color: var(--bs-dark);">HNS Available</span></div>
|
||||
<div class="text-dark fw-bold h5 mb-0"><span><img src="/assets/img/HNS.png" width="20px"> <span id="wallet-available">0.00</span></span></div>
|
||||
</div>
|
||||
<div class="col-auto"><i class="fas fa-dollar-sign fa-2x text-gray-300"></i></div>
|
||||
</div>
|
||||
@@ -81,12 +81,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-3 mb-4">
|
||||
<div class="card shadow py-2 border-start-success">
|
||||
<div class="card shadow border-start-success py-2">
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center no-gutters">
|
||||
<div class="col me-2">
|
||||
<div class="text-uppercase text-success mb-1 fw-bold text-xs"><span>HNS Total</span></div>
|
||||
<div class="text-dark mb-0 fw-bold h5"><span><img src="/assets/img/HNS.png" width="20px"> <span id="wallet-total">0.00</span></span></div>
|
||||
<div class="text-uppercase text-success fw-bold text-xs mb-1"><span>HNS Total</span></div>
|
||||
<div class="text-dark fw-bold h5 mb-0"><span><img src="/assets/img/HNS.png" width="20px"> <span id="wallet-total">0.00</span></span></div>
|
||||
</div>
|
||||
<div class="col-auto"><i class="fas fa-dollar-sign fa-2x text-gray-300"></i></div>
|
||||
</div>
|
||||
@@ -94,14 +94,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-3 mb-4">
|
||||
<div class="card shadow py-2 border-start-info">
|
||||
<div class="card shadow border-start-info py-2">
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center no-gutters">
|
||||
<div class="col me-2">
|
||||
<div class="text-uppercase text-info mb-1 fw-bold text-xs"><span>Domains</span></div>
|
||||
<div class="text-uppercase text-info fw-bold text-xs mb-1"><span>Domains</span></div>
|
||||
<div class="row g-0 align-items-center">
|
||||
<div class="col-auto">
|
||||
<div class="text-dark me-3 mb-0 fw-bold h5"><span id="wallet-domainCount">0</span></div>
|
||||
<div class="text-dark fw-bold h5 mb-0 me-3"><span id="wallet-domainCount">0</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -110,12 +110,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-3 mb-4">
|
||||
<div class="card shadow py-2 border-start-warning">
|
||||
<div class="card shadow border-start-warning py-2">
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center no-gutters">
|
||||
<div class="col me-2">
|
||||
<div class="text-uppercase text-warning mb-1 fw-bold text-xs"><span>Pending Transactions</span></div>
|
||||
<div class="text-dark mb-0 fw-bold h5"><span id="wallet-pending">0</span></div>
|
||||
<div class="text-uppercase text-warning fw-bold text-xs mb-1"><span>Pending Transactions</span></div>
|
||||
<div class="text-dark fw-bold h5 mb-0"><span id="wallet-pending">0</span></div>
|
||||
</div>
|
||||
<div class="col-auto"><svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="fa-2x text-gray-300">
|
||||
<g>
|
||||
@@ -135,19 +135,20 @@
|
||||
<div class="col">
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h6 class="text-primary m-0 fw-bold">Domains</h6>
|
||||
<h6 class="text-primary fw-bold m-0">Domains</h6>
|
||||
</div>
|
||||
<div class="card-body"><div class="table-responsive">
|
||||
<table class="table" id="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th onclick="sortTable(0)">Domain <span class="sort-indicator"></span></th>
|
||||
<th onclick="sortTable(1)" class="hide-mobile">Expires <span class="sort-indicator"></span></th>
|
||||
<th onclick="sortTable(2)" class="hide-mobile">Price Paid <span class="sort-indicator"></span></th>
|
||||
<!-- <th><span class="sort-indicator"></span></th> -->
|
||||
<th onclick="sortTable(1)">Expires <span class="sort-indicator"></span></th>
|
||||
<th onclick="sortTable(2)">Price Paid <span class="sort-indicator"></span></th>
|
||||
<th><span class="sort-indicator"></span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- {{domains | safe}} -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-9 col-lg-12 col-xl-10">
|
||||
<h1 class="text-center" style="color: var(--bs-danger);background: var(--bs-primary);">{{error}}</h1>
|
||||
<div class="card shadow-lg my-5 o-hidden border-0">
|
||||
<div class="card shadow-lg o-hidden border-0 my-5">
|
||||
<div class="card-body p-0">
|
||||
<div class="row">
|
||||
<div class="col-lg-6 d-none d-lg-flex">
|
||||
@@ -47,7 +47,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<div class="mb-3"><input class="form-control form-control-user" type="password" id="exampleInputPassword" placeholder="Password" name="password"></div><button class="btn btn-primary d-block w-100 btn-user" type="submit">Login</button>
|
||||
<div class="mb-3"><input class="form-control form-control-user" type="password" id="exampleInputPassword" placeholder="Password" name="password"></div><button class="btn btn-primary d-block btn-user w-100" type="submit">Login</button>
|
||||
<hr>
|
||||
</form>
|
||||
<div class="text-center"><a class="small" href="register">Create a wallet</a></div>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content" style="padding-bottom: 25px;">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -66,16 +66,15 @@
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">{{rendered}}<a class="btn btn-primary stick-right" role="button" href="/manage/{{domain}}/renew">Renew</a></h4>
|
||||
<h6 class="text-muted mb-2 card-subtitle">Expires in {{expiry}} days</h6>
|
||||
<h4 class="card-title">{{domain}}/<a class="btn btn-primary stick-right" role="button" href="/manage/{{domain}}/renew">Renew</a></h4>
|
||||
<h6 class="text-muted card-subtitle mb-2">Expires in {{expiry}} days</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>{{plugins|safe}}
|
||||
<div class="container-fluid" style="margin-top: 50px;">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" style="display: inline-block;">DNS</h4>
|
||||
<div style="width: fit-content;position: absolute;right: 0px;top: 16px;"><a class="btn btn-primary" role="button" href="https://tools.c.woodburn.au/?domain={{domain}}&url=https://{{domain}}" style="margin: 0px 16px;" target="_blank">Debug</a><a class="btn btn-primary" role="button" href="/manage/{{domain}}/edit?dns={{raw_dns}}" style="margin: 0px 16px;">Edit</a></div><div class="table-responsive">
|
||||
<h4 class="card-title" style="display: inline-block;">DNS</h4><a class="btn btn-primary" role="button" style="position: absolute; right:16px;" href="/manage/{{domain}}/edit?dns={{raw_dns}}">Edit</a><div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -64,7 +64,7 @@
|
||||
</nav>
|
||||
<div class="container-fluid" style="margin-bottom: 20px;">
|
||||
<h3 class="text-dark mb-1">{{name}}</h3>
|
||||
<h4 class="text-dark mb-1">{{description|safe}}</h4>{{output|safe}}
|
||||
<h4 class="text-dark mb-1">{{description}}</h4>{{output|safe}}
|
||||
</div>
|
||||
</div>
|
||||
<footer class="sticky-footer" style="background: var(--bs-primary-text-emphasis);">
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<body class="bg-gradient-primary">
|
||||
<div class="container">
|
||||
<div class="card shadow-lg my-5 o-hidden border-0">
|
||||
<div class="card shadow-lg o-hidden border-0 my-5">
|
||||
<div class="card-body p-0">
|
||||
<div class="row">
|
||||
<div class="col-lg-5 d-none d-lg-flex">
|
||||
@@ -30,11 +30,11 @@
|
||||
<h4 class="text-dark mb-4">Create a new wallet!</h4>
|
||||
</div>
|
||||
<form class="user" method="post">
|
||||
<div class="mb-3 row" style="padding-right: 16px;padding-left: 16px;"><input class="form-control form-control-user" type="text" id="exampleLastName" placeholder="Wallet name" name="name" value="{{name}}"></div>
|
||||
<div class="mb-3 row">
|
||||
<div class="row mb-3" style="padding-right: 16px;padding-left: 16px;"><input class="form-control form-control-user" type="text" id="exampleLastName" placeholder="Wallet name" name="name" value="{{name}}"></div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-6 mb-3 mb-sm-0"><input class="form-control form-control-user" type="password" id="examplePasswordInput" placeholder="Password" name="password" required="" value="{{password}}"></div>
|
||||
<div class="col-sm-6"><input class="form-control form-control-user" type="password" id="exampleRepeatPasswordInput" placeholder="Repeat Password" name="password_repeat" required="" value="{{password_repeat}}"></div>
|
||||
</div><button class="btn btn-primary d-block w-100 btn-user" type="submit">Create Wallet</button>
|
||||
</div><button class="btn btn-primary d-block btn-user w-100" type="submit">Create Wallet</button>
|
||||
<hr>
|
||||
</form>
|
||||
<div class="text-center"><a class="small" href="/login">Didn't mean to create a new wallet? Login!</a></div>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -65,10 +65,10 @@
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="d-none d-sm-none d-md-none d-lg-inline-block d-xl-inline-block card-title">{{rendered}}<span class="stick-right">{{next}}</span></h4>
|
||||
<h4 class="d-none d-sm-none d-md-none d-lg-inline-block d-xl-inline-block card-title">{{domain}}/<span class="stick-right">{{next}}</span></h4>
|
||||
<h4 class="d-print-none d-sm-inline-block d-md-inline-block d-lg-none d-xl-none d-xxl-none card-title">{{domain}}/<br><br><span class="stick-right">{{next}}</span></h4>
|
||||
<h6 class="text-muted mb-2 card-subtitle"><br>{{state}}</h6>
|
||||
<h6 class="text-muted mb-2 card-subtitle">Owner: {{owner}}</h6><a class="btn btn-primary" role="button" style="margin-right: 25px;" href="/manage/{{domain}}">Manage</a><a class="btn btn-primary" role="button" href="/auction/{{domain}}">Auction</a>
|
||||
<h6 class="text-muted card-subtitle mb-2"><br>{{state}}</h6>
|
||||
<h6 class="text-muted card-subtitle mb-2">Owner: {{owner}}</h6><a class="btn btn-primary" role="button" style="margin-right: 25px;" href="/manage/{{domain}}">Manage</a><a class="btn btn-primary" role="button" href="/auction/{{domain}}">Auction</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>{{plugins|safe}}
|
||||
@@ -87,6 +87,27 @@
|
||||
{{dns | safe}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid" style="margin-top: 50px;">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">History</h4><div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Action</th>
|
||||
<th>TX</th>
|
||||
<th>Amount</th>
|
||||
<th>Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{txs | safe}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -41,14 +41,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -57,7 +57,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" id="wallet-icon" src="/api/v1/wallet/icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -69,7 +69,7 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Node Settings</h4><small>HSD Version: v{{hsd_version}}</small>
|
||||
<h6 class="text-muted mb-2 card-subtitle">Settings that affect all wallets</h6>
|
||||
<h6 class="text-muted card-subtitle mb-2">Settings that affect all wallets</h6>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<div><a class="btn btn-primary stick-right" role="button" href="/settings/rescan">Rescan</a>
|
||||
@@ -94,7 +94,7 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Wallet Settings</h4>
|
||||
<h6 class="text-muted mb-2 card-subtitle">Settings that affect only current wallets</h6>
|
||||
<h6 class="text-muted card-subtitle mb-2">Settings that affect only current wallets</h6>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<div><a class="btn btn-primary stick-right" role="button" href="/settings/xpub">xPub</a>
|
||||
@@ -120,7 +120,7 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">About</h4>
|
||||
<h6 class="text-muted mb-2 card-subtitle">FireWallet is a UI to allow easy connection with HSD created by <a href="https://nathan.woodburn.au" target="_blank">Nathan.Woodburn/</a> and freely available. Please contact him <a href="https://l.woodburn.au/contact" target="_blank">here</a> if you would like to request any features or report any bugs.<br>FireWallet version: <code>{{version}}</code></h6>
|
||||
<h6 class="text-muted card-subtitle mb-2">FireWallet is a UI to allow easy connection with HSD created by <a href="https://nathan.woodburn.au" target="_blank">Nathan.Woodburn/</a> and freely available. Please contact him <a href="https://l.woodburn.au/contact" target="_blank">here</a> if you would like to request any features or report any bugs.<br>FireWallet version: <code>{{version}}</code></h6>
|
||||
<div class="text-center"><a href="https://github.com/nathanwoodburn/firewalletbrowser" style="margin: 15px;color: var(--bs-emphasis-color);text-decoration:none;" target="_blank"><i class="icon ion-social-github" style="color: var(--bs-emphasis-color);"></i> Github</a><a href="https://firewallet.au" style="margin: 15px;color: var(--bs-emphasis-color);text-decoration:none;" target="_blank"><i class="icon ion-ios-information" style="color: var(--bs-emphasis-color);"></i> Website</a><a href="https://l.woodburn.au/donate" style="margin: 15px;color: var(--bs-emphasis-color);text-decoration:none;" target="_blank"><i class="icon ion-social-usd" style="color: var(--bs-emphasis-color);"></i> Donate to support development</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -67,7 +67,7 @@
|
||||
</div>
|
||||
<div class="card" style="max-width: 500px;margin: auto;margin-top: 50px;">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Your transaction has been sent and will be mined soon.</h4><span style="display: block;font-size: 12px;">TX: {{tx}}</span><span style="display: block;">Check your transaction on a block explorer</span><a class="card-link" href="https://shakeshift.com/transaction/{{tx}}" target="_blank">ShakeShift</a><a class="card-link" href="https://3xpl.com/handshake/transaction/{{tx}}" target="_blank">3xpl</a>
|
||||
<h4 class="card-title">Your transaction has been sent and will be mined soon.</h4><span style="display: block;font-size: 12px;">TX: {{tx}}</span><span style="display: block;">Check your transaction on a block explorer</span><a class="card-link" href="https://niami.io/tx/{{tx}}" target="_blank">Niami</a><a class="card-link" href="https://3xpl.com/handshake/transaction/{{tx}}" target="_blank">3xpl</a><a class="card-link" href="https://hns.cymon.de/tx/{{tx}}" target="_blank">HNS.Cymon.de</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<body id="page-top">
|
||||
<div id="wrapper">
|
||||
<nav class="navbar align-items-start p-0 sidebar sidebar-dark accordion bg-gradient-primary navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center m-0 sidebar-brand" href="/">
|
||||
<nav class="navbar align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0 navbar-dark toggled" style="background: var(--bs-primary-border-subtle);">
|
||||
<div class="container-fluid d-flex flex-column p-0"><a class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="/">
|
||||
<div class="sidebar-brand-icon"><img src="/assets/img/favicon.png" width="44"></div>
|
||||
<div class="mx-3 sidebar-brand-text"><span>FireWallet</span></div>
|
||||
<div class="sidebar-brand-text mx-3"><span>FireWallet</span></div>
|
||||
</a>
|
||||
<hr class="my-0 sidebar-divider">
|
||||
<hr class="sidebar-divider my-0">
|
||||
<ul class="navbar-nav text-light" id="accordionSidebar">
|
||||
<li class="nav-item"><a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/tx"><i class="fas fa-table"></i><span>Transactions</span></a></li>
|
||||
@@ -40,14 +40,14 @@
|
||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||
<div id="content">
|
||||
<nav class="navbar navbar-expand shadow mb-4 topbar static-top navbar-light" style="background: var(--bs-primary-text-emphasis);">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none me-3 rounded-circle" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block mw-100 ms-md-3 me-auto my-2 my-md-0 navbar-search" action="/search" method="get">
|
||||
<div class="container-fluid"><button class="btn btn-link d-md-none rounded-circle me-3" id="sidebarToggleTop" type="button"><i class="fas fa-bars"></i></button>
|
||||
<form class="d-none d-sm-inline-block me-auto ms-md-3 my-2 my-md-0 mw-100 navbar-search" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for domain" name="q" value="{{search_term}}" style="color: var(--bs-dark-text-emphasis);background: var(--bs-light);"><button class="btn btn-primary py-0" type="submit"><i class="fas fa-search"></i></button></div>
|
||||
</form><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);"><span id="hsd-sync-mobile">{{sync}}</span></span><span class="d-inline d-print-none d-sm-inline d-md-inline d-lg-none d-xl-none d-xxl-none" style="color: var(--bs-dark);margin-left: 10px;"><span id="wallet-sync-mobile">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span class="d-none d-print-inline d-sm-none d-md-none d-lg-inline d-xl-inline d-xxl-inline" style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
</form><span style="color: var(--bs-dark);">Sync: <span id="hsd-sync">{{sync}}</span>%</span><span style="color: var(--bs-dark);margin-left: 10px;">Wallet: <span id="wallet-sync">{{wallet_status}}</span></span><span style="color: var(--bs-dark);margin-left: 10px;">Height: <span id="hsd-height">{{height}}</span></span>
|
||||
<ul class="navbar-nav flex-nowrap ms-auto">
|
||||
<li class="nav-item dropdown d-sm-none no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><i class="fas fa-search"></i></a>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-end animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="w-100 me-auto navbar-search" action="/search" method="get">
|
||||
<div class="dropdown-menu dropdown-menu-end p-3 animated--grow-in" aria-labelledby="searchDropdown">
|
||||
<form class="me-auto navbar-search w-100" action="/search" method="get">
|
||||
<div class="input-group"><input class="bg-light form-control border-0 small" type="text" placeholder="Search for ..." name="q" value="{{search_term}}">
|
||||
<div class="input-group-append"><button class="btn btn-primary py-0" type="button"><i class="fas fa-search"></i></button></div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<div class="nav-item dropdown no-arrow"><a class="dropdown-toggle nav-link" aria-expanded="false" data-bs-toggle="dropdown" href="#"><span class="d-none d-lg-inline me-2 small" style="color: var(--bs-dark);">{{account}}</span><img class="border rounded-circle img-profile" src="/api/v1/wallet/icon" id="wallet-icon"></a>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt me-2 fa-sm fa-fw text-gray-400"></i> Logout</a></div>
|
||||
<div class="dropdown-menu shadow dropdown-menu-end animated--grow-in"><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt fa-sm fa-fw me-2 text-gray-400"></i> Logout</a></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -71,10 +71,9 @@
|
||||
{% if page != 1 %}
|
||||
<a class="btn btn-primary" role="button" href="/tx?page={{page-1}}">Prev</a>
|
||||
{% endif %}
|
||||
<!-- {% if txCount == 100 %} -->
|
||||
<!-- {% endif %} -->
|
||||
{% if txCount == 100 %}
|
||||
<a class="btn btn-primary" role="button" href="/tx?page={{page+1}}">Next</a>
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -82,74 +81,27 @@
|
||||
<table id="dataTable" class="table my-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Transaction</th>
|
||||
<!-- <th class="hide-mobile">Address</th> -->
|
||||
<!-- <th class="amount-column">Amount</th> -->
|
||||
<th>Action</th>
|
||||
<th>Address</th>
|
||||
<th>Tx</th>
|
||||
<th>Confirmations</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="transactions-tbody">
|
||||
<tr id="loading-row">
|
||||
<td colspan="5" class="text-center">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<div class="mt-2">Loading transactions...</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- <tbody>
|
||||
{{tx|safe}} -->
|
||||
<tbody>
|
||||
{{tx|safe}}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td><strong>Date</strong></td>
|
||||
<td><strong>Transaction</strong></td>
|
||||
<!-- <td class="hide-mobile"><strong>Address</strong></td> -->
|
||||
<!-- <td class="amount-column"><strong>Amount</strong></td> -->
|
||||
<td><strong>Action</strong></td>
|
||||
<td><strong>Address</strong></td>
|
||||
<td><strong>Tx</strong></td>
|
||||
<td><strong>Confirmations</strong></td>
|
||||
<td><strong>Amount</strong></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const page = {{ page }};
|
||||
const tbody = document.getElementById('transactions-tbody');
|
||||
const loadingRow = document.getElementById('loading-row');
|
||||
|
||||
// Fetch transactions
|
||||
fetch(`/api/v1/wallet/transactions?page=${page}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.error) {
|
||||
tbody.innerHTML = `<tr><td colspan="5" class="text-center text-danger">Error: ${data.error}</td></tr>`;
|
||||
return;
|
||||
}
|
||||
|
||||
// Replace loading with actual transactions
|
||||
tbody.innerHTML = data.html;
|
||||
|
||||
// Update pagination buttons if needed
|
||||
updatePagination(data.txCount, page);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching transactions:', error);
|
||||
tbody.innerHTML = '<tr><td colspan="5" class="text-center text-danger">Failed to load transactions</td></tr>';
|
||||
});
|
||||
});
|
||||
|
||||
function updatePagination(txCount, currentPage) {
|
||||
// Update pagination buttons based on transaction count
|
||||
const prevBtn = document.querySelector('a[href*="page=' + (currentPage - 1) + '"]');
|
||||
const nextBtn = document.querySelector('a[href*="page=' + (currentPage + 1) + '"]');
|
||||
|
||||
if (currentPage <= 1 && prevBtn) {
|
||||
prevBtn.style.display = 'none';
|
||||
}
|
||||
if (txCount < 100 && nextBtn) {
|
||||
nextBtn.style.display = 'none';
|
||||
}
|
||||
}
|
||||
</script></div>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1 +1 @@
|
||||
[data-bs-theme=dark]{--bs-primary:#000000;--bs-primary-rgb:0,0,0;--bs-primary-text-emphasis:#666666;--bs-primary-bg-subtle:#000000;--bs-primary-border-subtle:#000000;--bs-light:#404040;--bs-light-rgb:64,64,64;--bs-light-text-emphasis:#8C8C8C;--bs-light-bg-subtle:#0D0D0D;--bs-light-border-subtle:#262626;--bs-dark:#ffffff;--bs-dark-rgb:255,255,255;--bs-dark-text-emphasis:#FFFFFF;--bs-dark-bg-subtle:#333333;--bs-dark-border-subtle:#999999}.btn-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#000000;--bs-btn-border-color:#000000;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#000000;--bs-btn-hover-border-color:#000000;--bs-btn-focus-shadow-rgb:217,217,217;--bs-btn-active-color:#fff;--bs-btn-active-bg:#000000;--bs-btn-active-border-color:#000000;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#000000;--bs-btn-disabled-border-color:#000000}.btn-outline-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-primary{--bs-btn-color:#000000;--bs-btn-border-color:#000000;--bs-btn-focus-shadow-rgb:0,0,0;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#000000;--bs-btn-hover-border-color:#000000;--bs-btn-active-color:#fff;--bs-btn-active-bg:#000000;--bs-btn-active-border-color:#000000;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#000000}.btn-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-light{--bs-btn-color:#fff;--bs-btn-bg:#404040;--bs-btn-border-color:#404040;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#363636;--bs-btn-hover-border-color:#333333;--bs-btn-focus-shadow-rgb:226,226,226;--bs-btn-active-color:#fff;--bs-btn-active-bg:#333333;--bs-btn-active-border-color:#303030;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#404040;--bs-btn-disabled-border-color:#404040}.btn-outline-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-light{--bs-btn-color:#404040;--bs-btn-border-color:#404040;--bs-btn-focus-shadow-rgb:64,64,64;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#404040;--bs-btn-hover-border-color:#404040;--bs-btn-active-color:#fff;--bs-btn-active-bg:#404040;--bs-btn-active-border-color:#404040;--bs-btn-disabled-color:#404040;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#404040}.btn-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-dark{--bs-btn-color:#000000;--bs-btn-bg:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#FFFFFF;--bs-btn-hover-border-color:#FFFFFF;--bs-btn-focus-shadow-rgb:38,38,38;--bs-btn-active-color:#000000;--bs-btn-active-bg:#FFFFFF;--bs-btn-active-border-color:#FFFFFF;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:#ffffff;--bs-btn-disabled-border-color:#ffffff}.btn-outline-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-dark{--bs-btn-color:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-focus-shadow-rgb:255,255,255;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#ffffff;--bs-btn-hover-border-color:#ffffff;--bs-btn-active-color:#000000;--bs-btn-active-bg:#ffffff;--bs-btn-active-border-color:#ffffff;--bs-btn-disabled-color:#ffffff;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffffff}::-webkit-resizer{display:none}.stick-right{position:absolute;right:25px}.error:after{content:attr(data-text);position:absolute;left:2px;text-shadow:-1px 0 #e74a3b;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:2s linear infinite alternate-reverse noise-anim}.error:before{content:attr(data-text);position:absolute;left:-2px;text-shadow:1px 0 #4e73df;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:3s linear infinite alternate-reverse noise-anim-2}.no-display{text-decoration:none}.amount-column{text-align:right;padding-right:10px;white-space:nowrap}.domain-name{text-decoration:none;color:var(--bs-body-color)}@media (max-width:768px){.hide-mobile{display:none!important}
|
||||
[data-bs-theme=dark]{--bs-primary:#000000;--bs-primary-rgb:0,0,0;--bs-primary-text-emphasis:#666666;--bs-primary-bg-subtle:#000000;--bs-primary-border-subtle:#000000;--bs-light:#404040;--bs-light-rgb:64,64,64;--bs-light-text-emphasis:#8C8C8C;--bs-light-bg-subtle:#0D0D0D;--bs-light-border-subtle:#262626;--bs-dark:#ffffff;--bs-dark-rgb:255,255,255;--bs-dark-text-emphasis:#FFFFFF;--bs-dark-bg-subtle:#333333;--bs-dark-border-subtle:#999999}.btn-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#000000;--bs-btn-border-color:#000000;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#000000;--bs-btn-hover-border-color:#000000;--bs-btn-focus-shadow-rgb:217,217,217;--bs-btn-active-color:#fff;--bs-btn-active-bg:#000000;--bs-btn-active-border-color:#000000;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#000000;--bs-btn-disabled-border-color:#000000}.btn-outline-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-primary{--bs-btn-color:#000000;--bs-btn-border-color:#000000;--bs-btn-focus-shadow-rgb:0,0,0;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#000000;--bs-btn-hover-border-color:#000000;--bs-btn-active-color:#fff;--bs-btn-active-bg:#000000;--bs-btn-active-border-color:#000000;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#000000}.btn-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-light{--bs-btn-color:#fff;--bs-btn-bg:#404040;--bs-btn-border-color:#404040;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#363636;--bs-btn-hover-border-color:#333333;--bs-btn-focus-shadow-rgb:226,226,226;--bs-btn-active-color:#fff;--bs-btn-active-bg:#333333;--bs-btn-active-border-color:#303030;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#404040;--bs-btn-disabled-border-color:#404040}.btn-outline-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-light{--bs-btn-color:#404040;--bs-btn-border-color:#404040;--bs-btn-focus-shadow-rgb:64,64,64;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#404040;--bs-btn-hover-border-color:#404040;--bs-btn-active-color:#fff;--bs-btn-active-bg:#404040;--bs-btn-active-border-color:#404040;--bs-btn-disabled-color:#404040;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#404040}.btn-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-dark{--bs-btn-color:#000000;--bs-btn-bg:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#FFFFFF;--bs-btn-hover-border-color:#FFFFFF;--bs-btn-focus-shadow-rgb:38,38,38;--bs-btn-active-color:#000000;--bs-btn-active-bg:#FFFFFF;--bs-btn-active-border-color:#FFFFFF;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:#ffffff;--bs-btn-disabled-border-color:#ffffff}.btn-outline-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-dark{--bs-btn-color:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-focus-shadow-rgb:255,255,255;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#ffffff;--bs-btn-hover-border-color:#ffffff;--bs-btn-active-color:#000000;--bs-btn-active-bg:#ffffff;--bs-btn-active-border-color:#ffffff;--bs-btn-disabled-color:#ffffff;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffffff}::-webkit-resizer{display:none}.stick-right{position:absolute;right:25px}.error:after{content:attr(data-text);position:absolute;left:2px;text-shadow:-1px 0 #e74a3b;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:2s linear infinite alternate-reverse noise-anim}.error:before{content:attr(data-text);position:absolute;left:-2px;text-shadow:1px 0 #4e73df;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:3s linear infinite alternate-reverse noise-anim-2}
|
||||
@@ -1 +1 @@
|
||||
[data-bs-theme=dark]{--bs-primary:#6e0e9c;--bs-primary-rgb:110,14,156;--bs-primary-text-emphasis:#A86EC4;--bs-primary-bg-subtle:#16031F;--bs-primary-border-subtle:#42085E;--bs-light:#404040;--bs-light-rgb:64,64,64;--bs-light-text-emphasis:#8C8C8C;--bs-light-bg-subtle:#0D0D0D;--bs-light-border-subtle:#262626;--bs-dark:#ffffff;--bs-dark-rgb:255,255,255;--bs-dark-text-emphasis:#FFFFFF;--bs-dark-bg-subtle:#333333;--bs-dark-border-subtle:#999999}.btn-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#6e0e9c;--bs-btn-border-color:#6e0e9c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5E0C85;--bs-btn-hover-border-color:#580B7D;--bs-btn-focus-shadow-rgb:233,219,240;--bs-btn-active-color:#fff;--bs-btn-active-bg:#580B7D;--bs-btn-active-border-color:#530B75;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6e0e9c;--bs-btn-disabled-border-color:#6e0e9c}.btn-outline-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-primary{--bs-btn-color:#6e0e9c;--bs-btn-border-color:#6e0e9c;--bs-btn-focus-shadow-rgb:110,14,156;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6e0e9c;--bs-btn-hover-border-color:#6e0e9c;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6e0e9c;--bs-btn-active-border-color:#6e0e9c;--bs-btn-disabled-color:#6e0e9c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6e0e9c}.btn-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-light{--bs-btn-color:#fff;--bs-btn-bg:#404040;--bs-btn-border-color:#404040;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#363636;--bs-btn-hover-border-color:#333333;--bs-btn-focus-shadow-rgb:226,226,226;--bs-btn-active-color:#fff;--bs-btn-active-bg:#333333;--bs-btn-active-border-color:#303030;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#404040;--bs-btn-disabled-border-color:#404040}.btn-outline-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-light{--bs-btn-color:#404040;--bs-btn-border-color:#404040;--bs-btn-focus-shadow-rgb:64,64,64;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#404040;--bs-btn-hover-border-color:#404040;--bs-btn-active-color:#fff;--bs-btn-active-bg:#404040;--bs-btn-active-border-color:#404040;--bs-btn-disabled-color:#404040;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#404040}.btn-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-dark{--bs-btn-color:#000000;--bs-btn-bg:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#FFFFFF;--bs-btn-hover-border-color:#FFFFFF;--bs-btn-focus-shadow-rgb:38,38,38;--bs-btn-active-color:#000000;--bs-btn-active-bg:#FFFFFF;--bs-btn-active-border-color:#FFFFFF;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:#ffffff;--bs-btn-disabled-border-color:#ffffff}.btn-outline-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-dark{--bs-btn-color:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-focus-shadow-rgb:255,255,255;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#ffffff;--bs-btn-hover-border-color:#ffffff;--bs-btn-active-color:#000000;--bs-btn-active-bg:#ffffff;--bs-btn-active-border-color:#ffffff;--bs-btn-disabled-color:#ffffff;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffffff}.stick-right{position:absolute;right:25px}.error:after{content:attr(data-text);position:absolute;left:2px;text-shadow:-1px 0 #e74a3b;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:2s linear infinite alternate-reverse noise-anim}.error:before{content:attr(data-text);position:absolute;left:-2px;text-shadow:1px 0 #4e73df;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:3s linear infinite alternate-reverse noise-anim-2}.no-display{text-decoration:none}.amount-column{text-align:right;padding-right:10px;white-space:nowrap}.domain-name{text-decoration:none;color:var(--bs-body-color)}@media (max-width:768px){.hide-mobile{display:none!important}
|
||||
[data-bs-theme=dark]{--bs-primary:#6e0e9c;--bs-primary-rgb:110,14,156;--bs-primary-text-emphasis:#A86EC4;--bs-primary-bg-subtle:#16031F;--bs-primary-border-subtle:#42085E;--bs-light:#404040;--bs-light-rgb:64,64,64;--bs-light-text-emphasis:#8C8C8C;--bs-light-bg-subtle:#0D0D0D;--bs-light-border-subtle:#262626;--bs-dark:#ffffff;--bs-dark-rgb:255,255,255;--bs-dark-text-emphasis:#FFFFFF;--bs-dark-bg-subtle:#333333;--bs-dark-border-subtle:#999999}.btn-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#6e0e9c;--bs-btn-border-color:#6e0e9c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5E0C85;--bs-btn-hover-border-color:#580B7D;--bs-btn-focus-shadow-rgb:233,219,240;--bs-btn-active-color:#fff;--bs-btn-active-bg:#580B7D;--bs-btn-active-border-color:#530B75;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6e0e9c;--bs-btn-disabled-border-color:#6e0e9c}.btn-outline-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-primary{--bs-btn-color:#6e0e9c;--bs-btn-border-color:#6e0e9c;--bs-btn-focus-shadow-rgb:110,14,156;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6e0e9c;--bs-btn-hover-border-color:#6e0e9c;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6e0e9c;--bs-btn-active-border-color:#6e0e9c;--bs-btn-disabled-color:#6e0e9c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6e0e9c}.btn-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-light{--bs-btn-color:#fff;--bs-btn-bg:#404040;--bs-btn-border-color:#404040;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#363636;--bs-btn-hover-border-color:#333333;--bs-btn-focus-shadow-rgb:226,226,226;--bs-btn-active-color:#fff;--bs-btn-active-bg:#333333;--bs-btn-active-border-color:#303030;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#404040;--bs-btn-disabled-border-color:#404040}.btn-outline-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-light{--bs-btn-color:#404040;--bs-btn-border-color:#404040;--bs-btn-focus-shadow-rgb:64,64,64;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#404040;--bs-btn-hover-border-color:#404040;--bs-btn-active-color:#fff;--bs-btn-active-bg:#404040;--bs-btn-active-border-color:#404040;--bs-btn-disabled-color:#404040;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#404040}.btn-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-dark{--bs-btn-color:#000000;--bs-btn-bg:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#FFFFFF;--bs-btn-hover-border-color:#FFFFFF;--bs-btn-focus-shadow-rgb:38,38,38;--bs-btn-active-color:#000000;--bs-btn-active-bg:#FFFFFF;--bs-btn-active-border-color:#FFFFFF;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:#ffffff;--bs-btn-disabled-border-color:#ffffff}.btn-outline-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-dark{--bs-btn-color:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-focus-shadow-rgb:255,255,255;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#ffffff;--bs-btn-hover-border-color:#ffffff;--bs-btn-active-color:#000000;--bs-btn-active-bg:#ffffff;--bs-btn-active-border-color:#ffffff;--bs-btn-disabled-color:#ffffff;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffffff}.stick-right{position:absolute;right:25px}.error:after{content:attr(data-text);position:absolute;left:2px;text-shadow:-1px 0 #e74a3b;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:2s linear infinite alternate-reverse noise-anim}.error:before{content:attr(data-text);position:absolute;left:-2px;text-shadow:1px 0 #4e73df;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:3s linear infinite alternate-reverse noise-anim-2}
|
||||
@@ -1 +1 @@
|
||||
[data-bs-theme=dark]{--bs-primary:#1a0023;--bs-primary-rgb:26,0,35;--bs-primary-text-emphasis:#76667B;--bs-primary-bg-subtle:#050007;--bs-primary-border-subtle:#100015;--bs-light:#404040;--bs-light-rgb:64,64,64;--bs-light-text-emphasis:#8C8C8C;--bs-light-bg-subtle:#0D0D0D;--bs-light-border-subtle:#262626;--bs-dark:#ffffff;--bs-dark-rgb:255,255,255;--bs-dark-text-emphasis:#FFFFFF;--bs-dark-bg-subtle:#333333;--bs-dark-border-subtle:#999999}.btn-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#1a0023;--bs-btn-border-color:#1a0023;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#16001E;--bs-btn-hover-border-color:#15001C;--bs-btn-focus-shadow-rgb:221,217,222;--bs-btn-active-color:#fff;--bs-btn-active-bg:#15001C;--bs-btn-active-border-color:#14001A;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#1a0023;--bs-btn-disabled-border-color:#1a0023}.btn-outline-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-primary{--bs-btn-color:#1a0023;--bs-btn-border-color:#1a0023;--bs-btn-focus-shadow-rgb:26,0,35;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#1a0023;--bs-btn-hover-border-color:#1a0023;--bs-btn-active-color:#fff;--bs-btn-active-bg:#1a0023;--bs-btn-active-border-color:#1a0023;--bs-btn-disabled-color:#1a0023;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#1a0023}.btn-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-light{--bs-btn-color:#fff;--bs-btn-bg:#404040;--bs-btn-border-color:#404040;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#363636;--bs-btn-hover-border-color:#333333;--bs-btn-focus-shadow-rgb:226,226,226;--bs-btn-active-color:#fff;--bs-btn-active-bg:#333333;--bs-btn-active-border-color:#303030;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#404040;--bs-btn-disabled-border-color:#404040}.btn-outline-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-light{--bs-btn-color:#404040;--bs-btn-border-color:#404040;--bs-btn-focus-shadow-rgb:64,64,64;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#404040;--bs-btn-hover-border-color:#404040;--bs-btn-active-color:#fff;--bs-btn-active-bg:#404040;--bs-btn-active-border-color:#404040;--bs-btn-disabled-color:#404040;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#404040}.btn-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-dark{--bs-btn-color:#000000;--bs-btn-bg:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#FFFFFF;--bs-btn-hover-border-color:#FFFFFF;--bs-btn-focus-shadow-rgb:38,38,38;--bs-btn-active-color:#000000;--bs-btn-active-bg:#FFFFFF;--bs-btn-active-border-color:#FFFFFF;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:#ffffff;--bs-btn-disabled-border-color:#ffffff}.btn-outline-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-dark{--bs-btn-color:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-focus-shadow-rgb:255,255,255;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#ffffff;--bs-btn-hover-border-color:#ffffff;--bs-btn-active-color:#000000;--bs-btn-active-bg:#ffffff;--bs-btn-active-border-color:#ffffff;--bs-btn-disabled-color:#ffffff;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffffff}.stick-right{position:absolute;right:25px}.error:after{content:attr(data-text);position:absolute;left:2px;text-shadow:-1px 0 #e74a3b;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:2s linear infinite alternate-reverse noise-anim}.error:before{content:attr(data-text);position:absolute;left:-2px;text-shadow:1px 0 #4e73df;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:3s linear infinite alternate-reverse noise-anim-2}.no-display{text-decoration:none}.amount-column{text-align:right;padding-right:10px;white-space:nowrap}.domain-name{text-decoration:none;color:var(--bs-body-color)}@media (max-width:768px){.hide-mobile{display:none!important}
|
||||
[data-bs-theme=dark]{--bs-primary:#1a0023;--bs-primary-rgb:26,0,35;--bs-primary-text-emphasis:#76667B;--bs-primary-bg-subtle:#050007;--bs-primary-border-subtle:#100015;--bs-light:#404040;--bs-light-rgb:64,64,64;--bs-light-text-emphasis:#8C8C8C;--bs-light-bg-subtle:#0D0D0D;--bs-light-border-subtle:#262626;--bs-dark:#ffffff;--bs-dark-rgb:255,255,255;--bs-dark-text-emphasis:#FFFFFF;--bs-dark-bg-subtle:#333333;--bs-dark-border-subtle:#999999}.btn-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#1a0023;--bs-btn-border-color:#1a0023;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#16001E;--bs-btn-hover-border-color:#15001C;--bs-btn-focus-shadow-rgb:221,217,222;--bs-btn-active-color:#fff;--bs-btn-active-bg:#15001C;--bs-btn-active-border-color:#14001A;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#1a0023;--bs-btn-disabled-border-color:#1a0023}.btn-outline-primary[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-primary{--bs-btn-color:#1a0023;--bs-btn-border-color:#1a0023;--bs-btn-focus-shadow-rgb:26,0,35;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#1a0023;--bs-btn-hover-border-color:#1a0023;--bs-btn-active-color:#fff;--bs-btn-active-bg:#1a0023;--bs-btn-active-border-color:#1a0023;--bs-btn-disabled-color:#1a0023;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#1a0023}.btn-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-light{--bs-btn-color:#fff;--bs-btn-bg:#404040;--bs-btn-border-color:#404040;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#363636;--bs-btn-hover-border-color:#333333;--bs-btn-focus-shadow-rgb:226,226,226;--bs-btn-active-color:#fff;--bs-btn-active-bg:#333333;--bs-btn-active-border-color:#303030;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#404040;--bs-btn-disabled-border-color:#404040}.btn-outline-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-light{--bs-btn-color:#404040;--bs-btn-border-color:#404040;--bs-btn-focus-shadow-rgb:64,64,64;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#404040;--bs-btn-hover-border-color:#404040;--bs-btn-active-color:#fff;--bs-btn-active-bg:#404040;--bs-btn-active-border-color:#404040;--bs-btn-disabled-color:#404040;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#404040}.btn-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-dark{--bs-btn-color:#000000;--bs-btn-bg:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#FFFFFF;--bs-btn-hover-border-color:#FFFFFF;--bs-btn-focus-shadow-rgb:38,38,38;--bs-btn-active-color:#000000;--bs-btn-active-bg:#FFFFFF;--bs-btn-active-border-color:#FFFFFF;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:#ffffff;--bs-btn-disabled-border-color:#ffffff}.btn-outline-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-dark{--bs-btn-color:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-focus-shadow-rgb:255,255,255;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#ffffff;--bs-btn-hover-border-color:#ffffff;--bs-btn-active-color:#000000;--bs-btn-active-bg:#ffffff;--bs-btn-active-border-color:#ffffff;--bs-btn-disabled-color:#ffffff;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffffff}.stick-right{position:absolute;right:25px}.error:after{content:attr(data-text);position:absolute;left:2px;text-shadow:-1px 0 #e74a3b;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:2s linear infinite alternate-reverse noise-anim}.error:before{content:attr(data-text);position:absolute;left:-2px;text-shadow:1px 0 #4e73df;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:3s linear infinite alternate-reverse noise-anim-2}
|
||||
@@ -1 +1 @@
|
||||
[data-bs-theme=dark]{--bs-light:#ffffff;--bs-light-rgb:255,255,255;--bs-light-text-emphasis:#FFFFFF;--bs-light-bg-subtle:#333333;--bs-light-border-subtle:#999999;--bs-dark:#000000;--bs-dark-rgb:0,0,0;--bs-dark-text-emphasis:#666666;--bs-dark-bg-subtle:#000000;--bs-dark-border-subtle:#000000}.btn-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-light{--bs-btn-color:#000000;--bs-btn-bg:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#D9D9D9;--bs-btn-hover-border-color:#CCCCCC;--bs-btn-focus-shadow-rgb:38,38,38;--bs-btn-active-color:#000000;--bs-btn-active-bg:#CCCCCC;--bs-btn-active-border-color:#BFBFBF;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:#ffffff;--bs-btn-disabled-border-color:#ffffff}.btn-outline-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-light{--bs-btn-color:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-focus-shadow-rgb:255,255,255;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#ffffff;--bs-btn-hover-border-color:#ffffff;--bs-btn-active-color:#000000;--bs-btn-active-bg:#ffffff;--bs-btn-active-border-color:#ffffff;--bs-btn-disabled-color:#ffffff;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffffff}.btn-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#000000;--bs-btn-border-color:#000000;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#000000;--bs-btn-hover-border-color:#000000;--bs-btn-focus-shadow-rgb:217,217,217;--bs-btn-active-color:#fff;--bs-btn-active-bg:#000000;--bs-btn-active-border-color:#000000;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#000000;--bs-btn-disabled-border-color:#000000}.btn-outline-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-dark{--bs-btn-color:#000000;--bs-btn-border-color:#000000;--bs-btn-focus-shadow-rgb:0,0,0;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#000000;--bs-btn-hover-border-color:#000000;--bs-btn-active-color:#fff;--bs-btn-active-bg:#000000;--bs-btn-active-border-color:#000000;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#000000}::-webkit-resizer{display:none}.stick-right{position:absolute;right:25px}.error:after{content:attr(data-text);position:absolute;left:2px;text-shadow:-1px 0 #e74a3b;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:2s linear infinite alternate-reverse noise-anim}.error:before{content:attr(data-text);position:absolute;left:-2px;text-shadow:1px 0 #4e73df;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:3s linear infinite alternate-reverse noise-anim-2}.no-display{text-decoration:none}.amount-column{text-align:right;padding-right:10px;white-space:nowrap}.domain-name{text-decoration:none;color:var(--bs-body-color)}@media (max-width:768px){.hide-mobile{display:none!important}
|
||||
[data-bs-theme=dark]{--bs-light:#ffffff;--bs-light-rgb:255,255,255;--bs-light-text-emphasis:#FFFFFF;--bs-light-bg-subtle:#333333;--bs-light-border-subtle:#999999;--bs-dark:#000000;--bs-dark-rgb:0,0,0;--bs-dark-text-emphasis:#666666;--bs-dark-bg-subtle:#000000;--bs-dark-border-subtle:#000000}.btn-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-light{--bs-btn-color:#000000;--bs-btn-bg:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#D9D9D9;--bs-btn-hover-border-color:#CCCCCC;--bs-btn-focus-shadow-rgb:38,38,38;--bs-btn-active-color:#000000;--bs-btn-active-bg:#CCCCCC;--bs-btn-active-border-color:#BFBFBF;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:#ffffff;--bs-btn-disabled-border-color:#ffffff}.btn-outline-light[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-light{--bs-btn-color:#ffffff;--bs-btn-border-color:#ffffff;--bs-btn-focus-shadow-rgb:255,255,255;--bs-btn-hover-color:#000000;--bs-btn-hover-bg:#ffffff;--bs-btn-hover-border-color:#ffffff;--bs-btn-active-color:#000000;--bs-btn-active-bg:#ffffff;--bs-btn-active-border-color:#ffffff;--bs-btn-disabled-color:#ffffff;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffffff}.btn-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#000000;--bs-btn-border-color:#000000;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#000000;--bs-btn-hover-border-color:#000000;--bs-btn-focus-shadow-rgb:217,217,217;--bs-btn-active-color:#fff;--bs-btn-active-bg:#000000;--bs-btn-active-border-color:#000000;--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#000000;--bs-btn-disabled-border-color:#000000}.btn-outline-dark[data-bs-theme=dark],[data-bs-theme=dark] .btn-outline-dark{--bs-btn-color:#000000;--bs-btn-border-color:#000000;--bs-btn-focus-shadow-rgb:0,0,0;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#000000;--bs-btn-hover-border-color:#000000;--bs-btn-active-color:#fff;--bs-btn-active-bg:#000000;--bs-btn-active-border-color:#000000;--bs-btn-disabled-color:#000000;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#000000}::-webkit-resizer{display:none}.stick-right{position:absolute;right:25px}.error:after{content:attr(data-text);position:absolute;left:2px;text-shadow:-1px 0 #e74a3b;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:2s linear infinite alternate-reverse noise-anim}.error:before{content:attr(data-text);position:absolute;left:-2px;text-shadow:1px 0 #4e73df;top:0;color:#5a5c69;background:var(--bs-primary);overflow:hidden;clip:rect(0,900px,0,0);animation:3s linear infinite alternate-reverse noise-anim-2}
|
||||
Reference in New Issue
Block a user