improve ux on managing wallets

master
lza_menace 2 years ago
parent 1af4fab245
commit 36da130b7d

@ -15,3 +15,4 @@ QUART_AUTH_DURATION = 60 * 60 # 1 hour
# LWS # LWS
LWS_URL = env.get("LWS_URL", "http://127.0.0.1:8080") LWS_URL = env.get("LWS_URL", "http://127.0.0.1:8080")
LWS_ADMIN_URL = env.get("LWS_ADMIN_URL", "http://127.0.0.1:8081") LWS_ADMIN_URL = env.get("LWS_ADMIN_URL", "http://127.0.0.1:8081")

@ -31,6 +31,28 @@ class Wallet(Model):
date_added = DateTimeField(null=True) date_added = DateTimeField(null=True)
user = ForeignKeyField(User, backref="wallets") user = ForeignKeyField(User, backref="wallets")
def is_active(self):
endpoint = f"{config.LWS_ADMIN_URL}/list_accounts"
data = {
"auth": self.user.view_key,
"params": {}
}
try:
req = requests.post(endpoint, json=data, timeout=5)
req.raise_for_status()
if req.ok:
res = req.json()
for _status in res:
for _wallet in res[_status]:
if _wallet["address"] == self.address:
if _status == "active":
return True
return False
return False
except Exception as e:
print(f"Failed to list wallets: {e}")
return False
def check_wallet_lws(self): def check_wallet_lws(self):
endpoint = f"{config.LWS_ADMIN_URL}/list_accounts" endpoint = f"{config.LWS_ADMIN_URL}/list_accounts"
data = { data = {
@ -81,13 +103,18 @@ class Wallet(Model):
print(f"Failed to add wallet {self.address}: {e}") print(f"Failed to add wallet {self.address}: {e}")
return False return False
def disable_wallet_lws(self): def set_active(self, status):
endpoint = f"{config.LWS_ADMIN_URL}/modify_account_status" endpoint = f"{config.LWS_ADMIN_URL}/modify_account_status"
_status = ""
if status:
_status = "active"
else:
_status = "inactive"
data = { data = {
"auth": self.user.view_key, "auth": self.user.view_key,
"params": { "params": {
"addresses": [self.address], "addresses": [self.address],
"status": "inactive" "status": _status
} }
} }
try: try:
@ -100,6 +127,24 @@ class Wallet(Model):
print(f"Failed to add wallet {self.address}: {e}") print(f"Failed to add wallet {self.address}: {e}")
return False return False
def enable_wallet_lws(self):
endpoint = f"{config.LWS_ADMIN_URL}/modify_account_status"
data = {
"auth": self.user.view_key,
"params": {
"addresses": [self.address],
"status": "inactive"
}
}
try:
req = requests.post(endpoint, json=data, timeout=5)
req.raise_for_status()
if req.ok:
return True
return False
except Exception as e:
print(f"Failed to add wallet {self.address}: {e}")
return False
def get_wallet_info(self): def get_wallet_info(self):
endpoint = f"{config.LWS_URL}/get_address_info" endpoint = f"{config.LWS_URL}/get_address_info"

@ -7,18 +7,26 @@ from lws.helpers import LWS
from lws import config from lws import config
bp = Blueprint('meta', 'meta') bp = Blueprint("meta", "meta")
@bp.route("/") @bp.route("/")
@login_required @login_required
async def index(): async def index():
wallets = Wallet.select().order_by(Wallet.date.desc()) admin = User.select().first()
lws = LWS(admin.view_key) lws = LWS(admin.view_key)
accounts = lws.list_accounts()
data = {}
for status in accounts:
if status == "hidden":
continue
for account in accounts[status]:
account["wallet"] = Wallet.select().where(Wallet.address ** account["address"]).first()
account["status"] = status
data[account["address"]] = account
return await render_template( return await render_template(
"index.html", "index.html",
config=config, config=config,
wallets=wallets, data=data
lws_accounts=lws.list_accounts()
) )

@ -18,13 +18,6 @@ bp = Blueprint('wallet', 'wallet')
# reject_requests: {"type": "import"|"create", "addresses":[...]} # reject_requests: {"type": "import"|"create", "addresses":[...]}
# rescan: {"height":..., "addresses":[...]} # rescan: {"height":..., "addresses":[...]}
@bp.route("/wallets")
@login_required
async def list():
wallets = Wallet.select().order_by(Wallet.id.asc())
return await render_template("wallet/list.html", wallets=wallets)
@bp.route("/wallet/add", methods=["GET", "POST"]) @bp.route("/wallet/add", methods=["GET", "POST"])
@login_required @login_required
async def add(): async def add():
@ -73,7 +66,7 @@ async def show(id):
wallet = Wallet.select().where(Wallet.id == id).first() wallet = Wallet.select().where(Wallet.id == id).first()
if not wallet: if not wallet:
await flash("wallet does not exist") await flash("wallet does not exist")
return redirect("/wallets") return redirect("/")
return await render_template( return await render_template(
"wallet/show.html", "wallet/show.html",
wallet=wallet wallet=wallet
@ -85,7 +78,7 @@ async def rescan(id):
wallet = Wallet.select().where(Wallet.id == id).first() wallet = Wallet.select().where(Wallet.id == id).first()
if not wallet: if not wallet:
await flash("wallet does not exist") await flash("wallet does not exist")
return redirect("/wallets") return redirect("/")
wallet.rescan() wallet.rescan()
return redirect(f"/wallet/{id}") return redirect(f"/wallet/{id}")
@ -96,7 +89,18 @@ async def disable(id):
wallet = Wallet.select().where(Wallet.id == id).first() wallet = Wallet.select().where(Wallet.id == id).first()
if not wallet: if not wallet:
await flash("wallet does not exist") await flash("wallet does not exist")
return redirect("/wallets") return redirect("/")
wallet.disable_wallet_lws() wallet.set_active(False)
return redirect(f"/wallet/{id}")
@bp.route("/wallet/<id>/enable")
@login_required
async def enable(id):
wallet = Wallet.select().where(Wallet.id == id).first()
if not wallet:
await flash("wallet does not exist")
return redirect("/")
wallet.set_active(True)
return redirect(f"/wallet/{id}") return redirect(f"/wallet/{id}")

@ -38,7 +38,6 @@
</a> </a>
</div> --> </div> -->
<div class="nav-right"> <div class="nav-right">
<a class="{% if request.path == '/wallets' %}active{% endif %}" href="/wallets">Wallets</a>
<a href="/logout">Logout</a> <a href="/logout">Logout</a>
</div> </div>
</nav> </nav>

@ -2,32 +2,47 @@
{% block content %} {% block content %}
<h1>LWS Web Admin</h1> <h1>LWS Web Admin</h1>
<a href="{{ url_for('wallet.list') }}" class="button outline primary">Manage Wallets</a>
<hr>
<p>LWS Admin: {{ config.LWS_ADMIN_URL }}</p> <p>LWS Admin: {{ config.LWS_ADMIN_URL }}</p>
<p>LWS RPC: {{ config.LWS_URL }}</p> <p>LWS RPC: {{ config.LWS_URL }}</p>
<h3>Active Accounts</h3> <h3>Accounts</h3>
<a href="/wallet/add" class="button outline primary">Add Wallet</a>
<table class="striped"> <table class="striped">
<thead> <thead>
<tr> <tr>
<th>Status</th> <th>Status</th>
<th>Wallet</th>
<th>Address</th> <th>Address</th>
<th>Description</th>
<th>Height</th> <th>Height</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for a in lws_accounts %} {% for address in data %}
{% if a != 'hidden' %} {% set _data = data[address] %}
{% for acc in lws_accounts[a] %}
<tr> <tr>
<td>{{ a | upper }}</td> <td>
<td>{{ acc['address'] | shorten }}</td> <button class="button {% if _data['status'] == 'active' %}success{% else %}error{% endif %}">
<td>{{ acc['scan_height'] }}</td> {{ _data['status'] | upper }}
</tr> </button>
{% endfor %} </td>
<td>
{% if _data['wallet'] %}
<a href="/wallet/{{ data[address]['wallet'].id }}">{{ data[address]['wallet'].name }}</a>
{% else %}
<a href="/wallet/add?address={{ address }}">add</a>
{% endif %}
</td>
<td>{{ address | shorten }}</td>
<td>
{% if _data['wallet'] %}
{{ _data['wallet'].description or "-" }}
{% else %}
-
{% endif %} {% endif %}
</td>
<td>{{ data[address]['scan_height'] }}</td>
</tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endblock %} {% endblock %}

@ -1,7 +1,7 @@
{% extends 'includes/base.html' %} {% extends 'includes/base.html' %}
{% block content %} {% block content %}
<a href="/wallets">Go Back</a> <a href="/">Go Back</a>
<h1>Add a Wallet</h1> <h1>Add a Wallet</h1>
<form method="post"> <form method="post">
<label for="name">Name</label> <label for="name">Name</label>
@ -9,7 +9,7 @@
<label for="description">Description</label> <label for="description">Description</label>
<input type="text" name="description" /> <input type="text" name="description" />
<label for="address">Address</label> <label for="address">Address</label>
<input type="text" name="address" /> <input type="text" name="address" value="{{ request.args.get('address', '') }}" />
<label for="view_key">View Key</label> <label for="view_key">View Key</label>
<input type="text" name="view_key" /> <input type="text" name="view_key" />
<label for="restore_height">Restore Height</label> <label for="restore_height">Restore Height</label>

@ -1,11 +0,0 @@
{% extends 'includes/base.html' %}
{% block content %}
<h1>Manage Wallets</h1>
<a class="button outline primary" href="{{ url_for('wallet.add') }}">Add a Wallet</a>
<div class="content">
{% for wallet in wallets %}
<p>{{ wallet.id }} - <a href="{{ url_for('wallet.show', id=wallet.id) }}">{{ wallet.name }}</a> - {{ wallet.description }} - {{ wallet.date }}</p>
{% endfor %}
</div>
{% endblock %}

@ -1,7 +1,7 @@
{% extends 'includes/base.html' %} {% extends 'includes/base.html' %}
{% block content %} {% block content %}
<a href="/wallets">Go Back</a> <a href="/">Go Back</a>
{% set info = wallet.get_wallet_info() %} {% set info = wallet.get_wallet_info() %}
<h1>{{ wallet.name }}</h1> <h1>{{ wallet.name }}</h1>
<h5>{{ wallet.description }}</h5> <h5>{{ wallet.description }}</h5>
@ -11,11 +11,17 @@
<p>Scanned Height: {{ info['scanned_height'] }} <span class="smol">({{ info['blockchain_height'] - info['scanned_height'] }} blocks away from top)</span></p> <p>Scanned Height: {{ info['scanned_height'] }} <span class="smol">({{ info['blockchain_height'] - info['scanned_height'] }} blocks away from top)</span></p>
<p>Chain Height: {{ info['blockchain_height'] }}</p> <p>Chain Height: {{ info['blockchain_height'] }}</p>
<p>Spent Outputs: {{ info['spent_outputs'] | length }}</p> <p>Spent Outputs: {{ info['spent_outputs'] | length }}</p>
{% if wallet.is_active() %}
<p>Status: active</p>
{% else %}
<p>Status: inactive</p>
{% endif %}
<a href="{{ url_for('wallet.rescan', id=wallet.id) }}" class="button dark outline">rescan</a> <a href="{{ url_for('wallet.rescan', id=wallet.id) }}" class="button dark outline">rescan</a>
{% if request.args.get('disable') %} {% if wallet.is_active() %}
<a href="{{ url_for('wallet.disable', id=wallet.id) }}" class="button error">are you sure?</a> <a href="{{ url_for('wallet.disable', id=wallet.id) }}" class="button error">disable</a>
{% else %} {% else %}
<a href="?disable=true" class="button error">disable</a> <a href="{{ url_for('wallet.enable', id=wallet.id) }}" class="button primary">enable</a>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
Loading…
Cancel
Save