improving wallet dashboard page, added transfer table, heights, and balances

mm-logging
lza_menace 4 years ago
parent fb5e93232a
commit 3e0cc311f7

@ -9,13 +9,21 @@ from wowstash.models import User
@wallet_bp.route("/wallet/dashboard")
@login_required
def dashboard():
all_transfers = list()
user = User.query.get(current_user.id)
wallet_height = wallet.height()['height']
daemon_height = daemon.height()['height']
subaddress = wallet.get_address(0, user.subaddress_index)['addresses'][0]['address']
subaddress = wallet.get_address(0, user.subaddress_index)
balances = wallet.get_balance(0, user.subaddress_index)
transfers = wallet.get_transfers(0, user.subaddress_index)
for type in transfers:
for tx in transfers[type]:
all_transfers.append(tx)
return render_template(
"wallet/dashboard.html",
wallet_height=wallet_height,
daemon=daemon_height,
subaddress=subaddress
daemon_height=daemon_height,
subaddress=subaddress,
balances=balances,
all_transfers=all_transfers
)

@ -4,6 +4,7 @@ from flask_session import Session
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from redis import Redis
from datetime import datetime
from wowstash import config
@ -61,6 +62,12 @@ def create_app():
from wowstash.models import User
return User.query.get(user_id)
# template filters
@app.template_filter('datestamp')
def datestamp(s):
d = datetime.fromtimestamp(s)
return d.strftime('%Y-%m-%d %H:%M:%S')
# Routes
from wowstash.blueprints.auth import auth_bp
from wowstash.blueprints.wallet import wallet_bp

@ -1,9 +1,12 @@
import json
import requests
import operator
from six import integer_types
from decimal import Decimal
from wowstash import config
PICOWOW = Decimal('0.00000000001')
class JSONRPC(object):
def __init__(self, proto, host, port, username='', password=''):
self.endpoint = '{}://{}:{}/'.format(
@ -53,7 +56,27 @@ class Wallet(JSONRPC):
def get_address(self, account_index, subaddress_index):
data = {'account_index': account_index, 'address_index': [subaddress_index]}
return self.make_rpc('get_address', data)
subaddress = self.make_rpc('get_address', data)['addresses'][0]['address']
return subaddress
def get_balance(self, account_index, subaddress_index):
data = {'account_index': account_index, 'address_indices': [subaddress_index]}
_balance = self.make_rpc('get_balance', data)
locked = from_atomic(_balance['per_subaddress'][0]['balance'])
unlocked = from_atomic(_balance['per_subaddress'][0]['unlocked_balance'])
return (float(locked), float(unlocked))
def get_transfers(self, account_index, subaddress_index):
data = {
'account_index': account_index,
'subaddr_indices': [subaddress_index],
'in': True,
'out': True,
'pending': True,
'failed': True,
'pool': True
}
return self.make_rpc('get_transfers', data)
class Daemon(JSONRPC):
@ -67,6 +90,19 @@ class Daemon(JSONRPC):
return self.make_rpc('get_height', {}, json_rpc=False)
def to_atomic(amount):
if not isinstance(amount, (Decimal, float) + integer_types):
raise ValueError("Amount '{}' doesn't have numeric type. Only Decimal, int, long and "
"float (not recommended) are accepted as amounts.")
return int(amount * 10**11)
def from_atomic(amount):
return (Decimal(amount) * PICOWOW).quantize(PICOWOW)
def as_wownero(amount):
return Decimal(amount).quantize(PICOWOW)
daemon = Daemon(
proto=config.DAEMON_PROTO,
host=config.DAEMON_HOST,

@ -501,3 +501,16 @@ footer ul li a:hover, footer ul li a:focus, footer ul li a:active, footer ul li
header.masthead .header-content-lg {
max-width: 70%;
}
@media (min-width: 992px) {
.tx-table {
display: inline-table;
margin: 0 auto
}
}
.slim {
width: 75%;
line-break: anywhere;
margin: auto;
}

@ -58,46 +58,6 @@
</div>
</section>
<!-- <header class="masthead">
<div class="container h-100">
<div class="row h-100">
<div class="col-lg-12 my-auto">
<div class="header-content mx-auto">
<form method="POST" action="{{ url_for('auth.register') }}">
{{ form.csrf_token }}
{% for f in form %}
{% if f.name != 'csrf_token' %}
{% if f.type == 'BooleanField' %}
<div class="form-group-span">
{{ f.label }}
{{ f }}
</div>
{% else %}
<div class="form-group">
{{ f.label }}
{{ f }}
</div>
{% endif %}
{% endif %}
{% endfor %}
<ul>
{% for field, errors in form.errors.items() %}
<li>{{ form[field].label }}: {{ ', '.join(errors) }}</li>
{% endfor %}
</ul>
<div>
<a href="{{ url_for('meta.faq') }}">FAQ</a> -
<a href="{{ url_for('meta.terms') }}">Terms</a> -
<a href="{{ url_for('meta.privacy') }}">Privacy</a>
</div><br>
<input type="submit" value="Register" class="btn btn-link btn-outline btn-xl">
</form>
</div>
</div>
</div>
</div>
</header> -->
{% include 'footer.html' %}
{% include 'scripts.html' %}

@ -3,13 +3,13 @@
<p>&copy; {{ config.SITE_NAME }} 2020. All Rights Reserved.</p>
<ul class="list-inline">
<li class="list-inline-item">
<a href="#">Privacy</a>
<a href="{{ url_for('meta.privacy') }}">Privacy</a>
</li>
<li class="list-inline-item">
<a href="#">Terms</a>
<a href="{{ url_for('meta.terms') }}">Terms</a>
</li>
<li class="list-inline-item">
<a href="#">FAQ</a>
<a href="{{ url_for('meta.faq') }}">FAQ</a>
</li>
</ul>
</div>

@ -5,7 +5,7 @@
<meta name="author" content="">
<link rel="stylesheet" href="/static/vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/vendor/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/css/new-age.css">
<link rel="stylesheet" href="/static/css/main.css">
<link rel="stylesheet" href="/static/css/noty.css">
<link rel="stylesheet" href="/static/css/noty-relax.css">
<title>{{ config.SITE_NAME }}</title>

@ -1,7 +1,7 @@
<script src="/static/vendor/jquery/jquery.min.js"></script>
<script src="/static/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="/static/vendor/jquery-easing/jquery.easing.min.js"></script>
<script src="/static/js/new-age.js"></script>
<script src="/static/js/main.js"></script>
<script src="/static/js/noty.js"></script>
{% with messages = get_flashed_messages() %}

@ -7,59 +7,20 @@
{% include 'navbar.html' %}
<!-- Height ({{ daemon_height }} / {{ wallet_height }})
Transactions - Send - Receive
Your Address
Transaction History
Balance: -->
<!-- <header class="masthead">
<div class="container h-100">
<div class="row h-100">
<div class="col-lg-4 my-auto">
<div class="header-content mx-auto">
<h2 class="mb-5">Welcome Back {{ current_user.email }}</h2>
<h3 class="sm">Account Address</h3>
<p class="small">address</p>
<h3 class="sm">Wallet Persistence</h3>
{% if wallet %}
<h3 class="sm">Account Balance</h3>
<p class="small">{{ h }}</p>
<h3 class="sm">Wallet File</h3>
<p class="small">{{ config.WALLET_PATH }}</p>
{% else %}
<h3 class="sm">Wallet Status</h3>
<p class="small">Not Connected</p>
{% endif %}
<a href="/account/wallet/" class="btn btn-outline btn-xl">Connect Wallet</a>
</div>
</div>
<div class="col-lg-6 my-auto">
<div class="header-content mx-auto">
<h1 class="mb-5">Logs</h1>
<h3 class="sm">Transaction Log</h3>
<p class="small">asd</p>
</div>
</div>
</div>
</div>
</header> -->
<section class="section2" id="">
<div class="container">
<!-- <div class="section-heading text-center">
<h2>Welcome</h2>
<p>Prices and network information</p>
<hr>
</div> -->
<div class="section-heading text-center">
<h2>Wallet Info</h2>
</div>
<div>
<p class="slim"><strong>Address:</strong> {{ subaddress }}</p>
<p>Balance: {{ balances.1 }} WOW (locked {{ balances.0 }} WOW)</p>
<p>Height ({{ wallet_height }} / {{ daemon_height }})</p>
</div>
<div class="row fp-row">
<div class="col-lg-4">
<a class="btn btn-lg btn-link btn-outline btn-xl" href="#">Transactions</a>
<a class="btn btn-lg btn-link btn-outline btn-xl js-scroll-trigger" href="#transfers">Transfers</a>
</div>
<div class="col-lg-4">
<a class="btn btn-lg btn-link btn-outline btn-xl" href="#">Send</a>
@ -68,26 +29,39 @@
<a class="btn btn-lg btn-link btn-outline btn-xl" href="#">Receive</a>
</div>
</div>
<div class="row fp-row">
<p>Your address: {{ subaddress }}</p>
</div>
</div>
</section>
<!-- <section class="section1" id="seed">
<section class="section1" id="transfers">
<div class="container">
<div class="section-heading text-center">
<h2>Manage your funds</h2>
<p class="text-muted">This is your mnemonic seed and account password.</p>
<p class="text-muted">Store it securely and never share it with anyone. Use this to log into {{ config.SITE_NAME }}.</p>
<p class="text-muted">If you'd like a new seed, refresh the page.</p>
<hr><br>
<p>{{ seed }}</p>
<hr><br>
<a href="/login" class="btn btn-outline-inverse btn-xl">Login</a>
<h2>Transfers</h2>
<p></p>
<table class="table table-striped table-hover table-responsive table-responsive-sm tx-table">
<tr>
<th>Date</th>
<th>Type</th>
<th>Tx ID</th>
<th>Amount</th>
<th>Confirmations</th>
<th>Fee</th>
</tr>
{% for tx in all_transfers | sort(attribute='timestamp', reverse=True) %}
{% if tx.type == 'pool' %}<tr class="table-warning">{% else %}<tr>{% endif %}
<td>{{ tx.timestamp | datestamp }}</td>
<td>{{ tx.type }}</td>
<td><a href="https://wownero.club/transaction/{{ tx.txid }}" target="_blank">{{ tx.txid | truncate(12) }}</a></td>
<td>{{ tx.amount / 100000000000 }}</td>
<td>{{ tx.confirmations }}</td>
<td>{{ tx.fee / 100000000000 }} WOW</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</section> -->
</section>
{% include 'footer.html' %}