Compare commits
10 Commits
dev
...
feat/notic
| Author | SHA1 | Date | |
|---|---|---|---|
|
59000afa87
|
|||
|
699a74f093
|
|||
|
6096f82c4d
|
|||
|
4353eb8fa4
|
|||
|
344cde07d0
|
|||
|
2fb841aeaf
|
|||
|
60df317f78
|
|||
|
4c1ea9fb12
|
|||
|
58ed636ce3
|
|||
|
e537c323c2
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -17,6 +17,6 @@ cache/
|
|||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
hsd/
|
hsd/
|
||||||
hsd-data/
|
hsd_data/
|
||||||
hsd.lock
|
hsd.lock
|
||||||
hsdconfig.json
|
hsdconfig.json
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ LABEL org.opencontainers.image.title="FireWallet (HSD)" \
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOLUME ["/app/hsd-data", "/app/user_data"]
|
VOLUME ["/app/hsd_data", "/app/user_data"]
|
||||||
|
|
||||||
|
|
||||||
ENTRYPOINT ["python3"]
|
ENTRYPOINT ["python3"]
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -13,6 +13,17 @@ cp example.env .env
|
|||||||
Edit .env to have your HSD api key.
|
Edit .env to have your HSD api key.
|
||||||
If you have HSD runnning on a separate computer also add the IP here
|
If you have HSD runnning on a separate computer also add the IP here
|
||||||
|
|
||||||
|
For a quick and easy installation on ubuntu/debian you can run the install.sh script
|
||||||
|
```bash
|
||||||
|
curl https://firewallet.au/install.sh | bash
|
||||||
|
```
|
||||||
|
This will install all dependencies (including Node/NPM for an internal HSD node), create a python virtual environment and install the required python packages.
|
||||||
|
After the script has run you can start the wallet with
|
||||||
|
```bash
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Make sure HSD is running then run the following commands:
|
Make sure HSD is running then run the following commands:
|
||||||
|
|||||||
@@ -1804,7 +1804,7 @@ def checkPreRequisites() -> dict[str, bool]:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# Check if git is installed
|
# Check if git is installed
|
||||||
gitSubprocess = subprocess.run(["git", "-v"], capture_output=True, text=True,timeout=2)
|
gitSubprocess = subprocess.run(["git", "--version"], capture_output=True, text=True,timeout=2)
|
||||||
if gitSubprocess.returncode == 0:
|
if gitSubprocess.returncode == 0:
|
||||||
prerequisites["git"] = True
|
prerequisites["git"] = True
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -1900,7 +1900,7 @@ def hsdStart():
|
|||||||
chain_migrate = HSD_CONFIG.get("chainMigrate", False)
|
chain_migrate = HSD_CONFIG.get("chainMigrate", False)
|
||||||
wallet_migrate = HSD_CONFIG.get("walletMigrate", False)
|
wallet_migrate = HSD_CONFIG.get("walletMigrate", False)
|
||||||
spv = HSD_CONFIG.get("spv", False)
|
spv = HSD_CONFIG.get("spv", False)
|
||||||
prefix = HSD_CONFIG.get("prefix", os.path.join(os.getcwd(), "hsd-data"))
|
prefix = HSD_CONFIG.get("prefix", os.path.join(os.getcwd(), "hsd_data"))
|
||||||
|
|
||||||
|
|
||||||
# Base command
|
# Base command
|
||||||
@@ -1976,7 +1976,6 @@ def hsdRestart():
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
hsdStart()
|
hsdStart()
|
||||||
|
|
||||||
|
|
||||||
hsdInit()
|
hsdInit()
|
||||||
hsdStart()
|
hsdStart()
|
||||||
# endregion
|
# endregion
|
||||||
@@ -4,10 +4,8 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "5000:5000"
|
- "5000:5000"
|
||||||
volumes:
|
volumes:
|
||||||
- hsd_data:/app/hsd-data
|
- hsd_data:/app/hsd_data
|
||||||
- user_data:/app/user_data
|
- user_data:/app/user_data
|
||||||
environment:
|
|
||||||
- INTERNAL_HSD=true
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
hsd_data:
|
hsd_data:
|
||||||
|
|||||||
81
install.sh
Executable file
81
install.sh
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
install_command=""
|
||||||
|
|
||||||
|
# Check if currently in the FireWalletBrowser directory
|
||||||
|
if [ -f "server.py" ]; then
|
||||||
|
echo "Please run this script from outside the FireWalletBrowser directory."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Starting installation of FireWalletBrowser..."
|
||||||
|
|
||||||
|
# Check if OS is using apt package manager (Debian/Ubuntu)
|
||||||
|
if command -v apt-get &> /dev/null; then
|
||||||
|
install_command="sudo apt-get install -y"
|
||||||
|
dependencies=(git curl wget python3 python3-pip python3-venv)
|
||||||
|
echo "Detected apt package manager."
|
||||||
|
# Check if OS is using pacman package manager (Arch Linux)
|
||||||
|
elif command -v pacman &> /dev/null; then
|
||||||
|
install_command="sudo pacman -S"
|
||||||
|
dependencies=(git curl wget python3 python-pip)
|
||||||
|
echo "Detected pacman package manager."
|
||||||
|
else
|
||||||
|
echo "Unsupported package manager. Please install dependencies manually."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# List of dependencies to install
|
||||||
|
# Install dependencies
|
||||||
|
for package in "${dependencies[@]}"; do
|
||||||
|
# Check if the package is already installed
|
||||||
|
if command -v $package &> /dev/null || dpkg -s $package &> /dev/null || pacman -Qi $package &> /dev/null; then
|
||||||
|
echo "$package is already installed."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo "Installing $package..."
|
||||||
|
$install_command $package
|
||||||
|
# Check if the installation was successful
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Failed to install $package. Please check your package manager settings."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if ! command -v node &> /dev/null || ! command -v npm &> /dev/null; then
|
||||||
|
echo "Installing Node.js and npm..."
|
||||||
|
# Download and install nvm:
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
|
||||||
|
# in lieu of restarting the shell
|
||||||
|
\. "$HOME/.nvm/nvm.sh"
|
||||||
|
nvm install 20
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Failed to install Node.js and npm. Please install them manually."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Node.js and npm are already installed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clone repo
|
||||||
|
git clone https://git.woodburn.au/nathanwoodburn/firewalletbrowser.git
|
||||||
|
|
||||||
|
# Setup venv
|
||||||
|
cd firewalletbrowser || exit 1
|
||||||
|
python3 -m venv .venv
|
||||||
|
source .venv/bin/activate
|
||||||
|
|
||||||
|
# Install python dependencies
|
||||||
|
python3 -m pip install -r requirements.txt
|
||||||
|
|
||||||
|
# Write .env file
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
echo "Creating .env file..."
|
||||||
|
echo "INTERNAL_HSD=true" > .env
|
||||||
|
echo "Created .env file with INTERNAL Node enabled."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installation complete. You can start the application by running ./start.sh"
|
||||||
112
main.py
112
main.py
@@ -1,6 +1,7 @@
|
|||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
|
import sqlite3
|
||||||
import sys
|
import sys
|
||||||
from flask import Flask, make_response, redirect, request, jsonify, render_template, send_from_directory,send_file
|
from flask import Flask, make_response, redirect, request, jsonify, render_template, send_from_directory,send_file
|
||||||
import os
|
import os
|
||||||
@@ -84,6 +85,13 @@ def index():
|
|||||||
print("New version available",flush=True)
|
print("New version available",flush=True)
|
||||||
plugins += render_template('components/dashboard-alert.html', name='Update', output='A new version of FireWallet is available')
|
plugins += render_template('components/dashboard-alert.html', name='Update', output='A new version of FireWallet is available')
|
||||||
|
|
||||||
|
alerts = get_alerts(account)
|
||||||
|
for alert in alerts:
|
||||||
|
output_html = alert['output']
|
||||||
|
# Add a dismiss button
|
||||||
|
output_html += f" <a href='/dismiss/{alert['id']}' class='btn btn-secondary btn-sm' style='margin:none;'>Dismiss</a>"
|
||||||
|
plugins += render_template('components/dashboard-alert.html', name=alert['name'], output=output_html)
|
||||||
|
|
||||||
return render_template("index.html", account=account, plugins=plugins)
|
return render_template("index.html", account=account, plugins=plugins)
|
||||||
|
|
||||||
def reverseDirection(direction: str):
|
def reverseDirection(direction: str):
|
||||||
@@ -1430,7 +1438,7 @@ def import_wallet():
|
|||||||
name=account,password=password,password_repeat=repeatPassword,
|
name=account,password=password,password_repeat=repeatPassword,
|
||||||
seed=seed)
|
seed=seed)
|
||||||
|
|
||||||
|
add_alert("Rescan needed", "Please rescan the wallet after importing to see all transactions", account)
|
||||||
# Set the cookie
|
# Set the cookie
|
||||||
response = make_response(redirect("/"))
|
response = make_response(redirect("/"))
|
||||||
response.set_cookie("account", account+":"+password)
|
response.set_cookie("account", account+":"+password)
|
||||||
@@ -1873,6 +1881,108 @@ def renderDomain(name: str) -> str:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return f"{name}/"
|
return f"{name}/"
|
||||||
|
|
||||||
|
def get_alerts(account:str) -> list:
|
||||||
|
"""
|
||||||
|
Get alerts to show on the dashboard.
|
||||||
|
"""
|
||||||
|
|
||||||
|
alerts = []
|
||||||
|
|
||||||
|
# Check if the node is connected
|
||||||
|
if not account_module.hsdConnected():
|
||||||
|
alerts.append({
|
||||||
|
"name": "Node",
|
||||||
|
"output": "HSD node is not connected. Please check your settings."
|
||||||
|
})
|
||||||
|
return alerts
|
||||||
|
|
||||||
|
# Check if the wallet is synced
|
||||||
|
wallet_status = account_module.getWalletStatus()
|
||||||
|
if wallet_status != "Ready":
|
||||||
|
alerts.append({
|
||||||
|
"name": "Wallet",
|
||||||
|
"output": f"The wallet is not synced ({wallet_status}). Please wait for it to sync."
|
||||||
|
})
|
||||||
|
print(account)
|
||||||
|
# Try to read from notifications sqlite database
|
||||||
|
if os.path.exists("user_data/notifications.db"):
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect("user_data/notifications.db")
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("SELECT id, name, message FROM notifications WHERE read=0 AND (account=? OR account='all')", (account,))
|
||||||
|
rows = c.fetchall()
|
||||||
|
for row in rows:
|
||||||
|
alerts.append({
|
||||||
|
"id": row[0],
|
||||||
|
"name": row[1],
|
||||||
|
"output": row[2]
|
||||||
|
})
|
||||||
|
conn.close()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error reading notifications: {e}",flush=True)
|
||||||
|
pass
|
||||||
|
|
||||||
|
return alerts
|
||||||
|
|
||||||
|
def add_alert(name:str,output:str,account:str="all"):
|
||||||
|
"""
|
||||||
|
Add an alert to the notifications database.
|
||||||
|
|
||||||
|
name: Name of the alert
|
||||||
|
output: Message of the alert
|
||||||
|
account: Account to add the alert for (default: all)
|
||||||
|
"""
|
||||||
|
if not os.path.exists("user_data/notifications.db"):
|
||||||
|
conn = sqlite3.connect("user_data/notifications.db")
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("CREATE TABLE notifications (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, message TEXT, account TEXT, read INTEGER DEFAULT 0)")
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect("user_data/notifications.db")
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("INSERT INTO notifications (name, message, account) VALUES (?, ?, ?)", (name, output, account))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error adding notification: {e}",flush=True)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def dismiss_alert(alert_id:int,account:str="all"):
|
||||||
|
"""
|
||||||
|
Mark an alert as read.
|
||||||
|
|
||||||
|
alert_id: ID of the alert to dismiss
|
||||||
|
account: Account to dismiss the alert for (default: all)
|
||||||
|
"""
|
||||||
|
if not os.path.exists("user_data/notifications.db"):
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect("user_data/notifications.db")
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("UPDATE notifications SET read=1 WHERE id=?", (alert_id,))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error dismissing notification: {e}",flush=True)
|
||||||
|
pass
|
||||||
|
|
||||||
|
@app.route('/dismiss/<int:alert_id>')
|
||||||
|
@app.route('/api/v1/dismiss/<int:alert_id>')
|
||||||
|
def dismiss_alert_route(alert_id):
|
||||||
|
# Check if the user is logged in
|
||||||
|
if request.cookies.get("account") is None:
|
||||||
|
return redirect("/login")
|
||||||
|
|
||||||
|
account = account_module.check_account(request.cookies.get("account"))
|
||||||
|
if not account:
|
||||||
|
return redirect("/logout")
|
||||||
|
|
||||||
|
dismiss_alert(alert_id,account)
|
||||||
|
return redirect(request.referrer or "/")
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user