Compare commits
4 Commits
f2cda461ba
...
feat/inter
| Author | SHA1 | Date | |
|---|---|---|---|
|
b76b873036
|
|||
|
23e714fad8
|
|||
|
a36c69ecfc
|
|||
|
1fd9987bf1
|
Binary file not shown.
19
README.md
19
README.md
@@ -143,6 +143,25 @@ If you set INTERNAL_HSD=true in the .env file the wallet will start and manage i
|
||||
}
|
||||
```
|
||||
|
||||
Supported config options are:
|
||||
```yaml
|
||||
spv: true/false
|
||||
prefix: path to hsd data directory
|
||||
flags: list of additional flags to pass to hsd
|
||||
version: version of hsd to use (used when installing HSD from source)
|
||||
chainMigrate: <int> (for users migrating from older versions of HSD)
|
||||
walletMigrate: <int> (for users migrating from older versions of HSD)
|
||||
```
|
||||
|
||||
## Support the Project
|
||||
|
||||
If you find FireWallet useful and would like to support its continued development, please consider making a donation. Your contributions help maintain the project and develop new features.
|
||||
|
||||
HNS donations can be sent to: `hs1qh7uzytf2ftwkd9dmjjs7az9qfver5m7dd7x4ej`
|
||||
Other donation options can be found at [my website](https://nathan.woodburn.au/donate)
|
||||
|
||||
Thank you for your support!
|
||||
|
||||
## Warnings
|
||||
|
||||
- This is a work in progress and is not guaranteed to work
|
||||
|
||||
105
account.py
105
account.py
@@ -64,7 +64,8 @@ HSD_CONFIG = {
|
||||
]
|
||||
}
|
||||
|
||||
CACHE_TTL = int(os.getenv("CACHE_TTL",90))
|
||||
TX_CACHE_TTL = 3600
|
||||
DOMAIN_CACHE_TTL = int(os.getenv("CACHE_TTL",90))
|
||||
|
||||
if not os.path.exists('hsdconfig.json'):
|
||||
with open('hsdconfig.json', 'w') as f:
|
||||
@@ -78,8 +79,6 @@ else:
|
||||
hsd = api.hsd(HSD_API, HSD_IP, HSD_NODE_PORT)
|
||||
hsw = api.hsw(HSD_API, HSD_IP, HSD_WALLET_PORT)
|
||||
|
||||
cacheTime = 3600
|
||||
|
||||
# Verify the connection
|
||||
response = hsd.getInfo()
|
||||
|
||||
@@ -377,7 +376,7 @@ def getBalance(account: str):
|
||||
cursor = conn.cursor()
|
||||
|
||||
now = int(time.time())
|
||||
cache_cutoff = now - (CACHE_TTL * 86400) # Cache TTL in days
|
||||
cache_cutoff = now - (DOMAIN_CACHE_TTL * 86400) # Cache TTL in days
|
||||
|
||||
for domain in domains:
|
||||
domain_name = domain['name']
|
||||
@@ -488,40 +487,74 @@ def getDomains(account, own=True):
|
||||
|
||||
return domains
|
||||
|
||||
def init_tx_page_db():
|
||||
"""Initialize the SQLite database for transaction page cache."""
|
||||
os.makedirs('cache', exist_ok=True)
|
||||
db_path = os.path.join('cache', 'tx_pages.db')
|
||||
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Create the tx_pages table if it doesn't exist
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS tx_pages (
|
||||
account TEXT,
|
||||
page_key TEXT,
|
||||
txid TEXT,
|
||||
timestamp INTEGER,
|
||||
PRIMARY KEY (account, page_key)
|
||||
)
|
||||
''')
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def getPageTXCache(account, page, size=100):
|
||||
page = f"{page}-{size}"
|
||||
if not os.path.exists(f'cache'):
|
||||
os.mkdir(f'cache')
|
||||
"""Get cached transaction ID from SQLite database."""
|
||||
account = getxPub(account)
|
||||
page_key = f"{page}-{size}"
|
||||
|
||||
if not os.path.exists(f'cache/{account}_page.json'):
|
||||
with open(f'cache/{account}_page.json', 'w') as f:
|
||||
f.write('{}')
|
||||
with open(f'cache/{account}_page.json') as f:
|
||||
pageCache = json.load(f)
|
||||
# Initialize database if needed
|
||||
init_tx_page_db()
|
||||
|
||||
if page in pageCache and pageCache[page]['time'] > int(time.time()) - cacheTime:
|
||||
return pageCache[page]['txid']
|
||||
db_path = os.path.join('cache', 'tx_pages.db')
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Query for the cached transaction ID
|
||||
cursor.execute(
|
||||
'SELECT txid, timestamp FROM tx_pages WHERE account = ? AND page_key = ?',
|
||||
(account, page_key)
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
conn.close()
|
||||
|
||||
if row and row[1] > int(time.time()) - TX_CACHE_TTL:
|
||||
return row[0] # Return the cached txid
|
||||
return None
|
||||
|
||||
|
||||
def pushPageTXCache(account, page, txid, size=100):
|
||||
page = f"{page}-{size}"
|
||||
if not os.path.exists(f'cache/{account}_page.json'):
|
||||
with open(f'cache/{account}_page.json', 'w') as f:
|
||||
f.write('{}')
|
||||
with open(f'cache/{account}_page.json') as f:
|
||||
pageCache = json.load(f)
|
||||
"""Store transaction ID in SQLite database."""
|
||||
account = getxPub(account)
|
||||
page_key = f"{page}-{size}"
|
||||
|
||||
pageCache[page] = {
|
||||
'time': int(time.time()),
|
||||
'txid': txid
|
||||
}
|
||||
with open(f'cache/{account}_page.json', 'w') as f:
|
||||
json.dump(pageCache, f, indent=4)
|
||||
# Initialize database if needed
|
||||
init_tx_page_db()
|
||||
|
||||
return pageCache[page]['txid']
|
||||
db_path = os.path.join('cache', 'tx_pages.db')
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Insert or replace the transaction ID
|
||||
cursor.execute(
|
||||
'INSERT OR REPLACE INTO tx_pages (account, page_key, txid, timestamp) VALUES (?, ?, ?, ?)',
|
||||
(account, page_key, txid, int(time.time()))
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
return txid
|
||||
|
||||
def getTXFromPage(account, page, size=100):
|
||||
if page == 1:
|
||||
@@ -740,7 +773,6 @@ def getDomain(domain: str):
|
||||
"message": response['error']['message']
|
||||
}
|
||||
}
|
||||
|
||||
return response['result']
|
||||
|
||||
def isKnownDomain(domain: str) -> bool:
|
||||
@@ -783,6 +815,17 @@ def renewDomain(account, domain):
|
||||
|
||||
def getDNS(domain: str):
|
||||
# Get the DNS
|
||||
|
||||
if isSPV():
|
||||
response = requests.get(f"https://hsd.hns.au/api/v1/nameresource/{domain}")
|
||||
if response.status_code != 200:
|
||||
return {
|
||||
"error": f"Error fetching DNS records: {response.status_code}"
|
||||
}
|
||||
response = response.json()
|
||||
return response.get('records', [])
|
||||
|
||||
|
||||
response = hsd.rpc_getNameResource(domain)
|
||||
if response['error'] is not None:
|
||||
return {
|
||||
@@ -1569,6 +1612,8 @@ def zapTXs(account):
|
||||
|
||||
|
||||
def getxPub(account):
|
||||
account_name = account
|
||||
if account.count(":") > 0:
|
||||
account_name = check_account(account)
|
||||
|
||||
if account_name == False:
|
||||
@@ -1587,8 +1632,6 @@ def getxPub(account):
|
||||
}
|
||||
}
|
||||
return response['accountKey']
|
||||
|
||||
return response
|
||||
except Exception as e:
|
||||
return {
|
||||
"error": {
|
||||
|
||||
45
grant.md
45
grant.md
@@ -1,45 +0,0 @@
|
||||
What have you built previously?
|
||||
- [HNSHosting](https://hnshosting.au)
|
||||
- [ShakeCities](https://shakecities.com)
|
||||
- [FireWallet](https://firewallet.au)
|
||||
- [Git Profile](https://github.com/nathanwoodburn)
|
||||
|
||||
Project summary
|
||||
A Handshake wallet web ui. This will be a HSD wallet web ui that will allow users to manage their Handshake domains via a web interface. This will allow users to easily manage their domains without having to use the command line or bob. One benefit of this is that it will allow users to easily manage their domains from their mobile devices that don't have access to any HNS wallet. This could be done in a secure way by only allowing connections on local network devices (in addition to requiring the wallet credentials).
|
||||
|
||||
Features:
|
||||
- Login with HSD wallet name + password (by default don't show a list of wallets to login to as this could be a security risk)
|
||||
- View account information in a dashboard
|
||||
- Available balance
|
||||
- Total balance
|
||||
- Pending Transactions
|
||||
- List of domains
|
||||
- List of transactions
|
||||
- Manage domains
|
||||
- Transfer domains
|
||||
- Finalize domains
|
||||
- Edit domains
|
||||
- Revoke domains (with a warning and requiring the account password)
|
||||
- Manage wallet
|
||||
- Send HNS
|
||||
- Receive HNS
|
||||
- Auctions
|
||||
- View bids on domain
|
||||
- Open auction
|
||||
- Bid on auction
|
||||
- Reveal bid
|
||||
- Redeem bid
|
||||
- Register domain
|
||||
|
||||
Completion requirements:
|
||||
- Basic functionality including
|
||||
- View info
|
||||
- Send/Receive HNS
|
||||
- Manage domains
|
||||
|
||||
After the initial version is completed I will be looking to add more features including the above mentioned features.
|
||||
|
||||
|
||||
The initial version will be completed in 2-3 weeks with a fully fledged version released later as the features are developed and tested.
|
||||
|
||||
You can contact me at handshake @ nathan.woodburn.au
|
||||
12
main.py
12
main.py
@@ -1148,15 +1148,20 @@ def settings():
|
||||
if success == None:
|
||||
success = ""
|
||||
|
||||
|
||||
if not os.path.exists(".git"):
|
||||
return render_template("settings.html", account=account,
|
||||
hsd_version=account_module.hsdVersion(False),
|
||||
error=error,success=success,version="Error",internal=account_module.HSD_INTERNAL_NODE)
|
||||
error=error,success=success,version="Error",
|
||||
internal=account_module.HSD_INTERNAL_NODE,
|
||||
spv=account_module.isSPV())
|
||||
info = gitinfo.get_git_info()
|
||||
if not info:
|
||||
return render_template("settings.html", account=account,
|
||||
hsd_version=account_module.hsdVersion(False),
|
||||
error=error,success=success,version="Error",internal=account_module.HSD_INTERNAL_NODE)
|
||||
error=error,success=success,version="Error",
|
||||
internal=account_module.HSD_INTERNAL_NODE,
|
||||
spv=account_module.isSPV())
|
||||
|
||||
branch = info['refs']
|
||||
if branch != "main":
|
||||
@@ -1171,7 +1176,8 @@ def settings():
|
||||
version += ' (New version available)'
|
||||
return render_template("settings.html", account=account,
|
||||
hsd_version=account_module.hsdVersion(False),
|
||||
error=error,success=success,version=version,internal=account_module.HSD_INTERNAL_NODE)
|
||||
error=error,success=success,version=version,internal=account_module.HSD_INTERNAL_NODE,
|
||||
spv=account_module.isSPV())
|
||||
|
||||
@app.route('/settings/<action>')
|
||||
def settings_action(action):
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<h3 class="mb-1" style="text-align: center;color: rgb(0,255,0);">{{success}}</h3>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Node Settings</h4><small>HSD Version: v{{hsd_version}}</small>
|
||||
<h4 class="card-title">Node Settings</h4><small>HSD Version: v{{hsd_version}} Type: {% if internal %} Internal {% else %} Remote {% endif %} ({% if spv %}SPV{% else %}Full Node{% endif %})</small>
|
||||
<h6 class="text-muted mb-2 card-subtitle">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>
|
||||
|
||||
Reference in New Issue
Block a user