modify workflow to allow seed restoral
This commit is contained in:
parent
a43fae4a1b
commit
13b1b9e1a9
|
@ -35,7 +35,7 @@ def register():
|
|||
# Capture event, login user and redirect to wallet page
|
||||
send_es({'type': 'register', 'user': user.email})
|
||||
login_user(user)
|
||||
return redirect(url_for('wallet.dashboard'))
|
||||
return redirect(url_for('wallet.setup'))
|
||||
|
||||
return render_template("auth/register.html", form=form)
|
||||
|
||||
|
|
|
@ -13,12 +13,31 @@ from wowstash.library.docker import docker
|
|||
from wowstash.library.elasticsearch import send_es
|
||||
from wowstash.library.jsonrpc import Wallet, to_atomic
|
||||
from wowstash.library.cache import cache
|
||||
from wowstash.forms import Send, Delete
|
||||
from wowstash.forms import Send, Delete, Restore
|
||||
from wowstash.factory import db
|
||||
from wowstash.models import User
|
||||
from wowstash import config
|
||||
|
||||
|
||||
@wallet_bp.route('/wallet/setup', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def setup():
|
||||
if current_user.wallet_created:
|
||||
return redirect(url_for('wallet.dashboard'))
|
||||
restore_form = Restore()
|
||||
if restore_form.validate_on_submit():
|
||||
if current_user.wallet_created is False:
|
||||
docker.create_wallet(current_user.id, restore_form.seed.data)
|
||||
current_user.wallet_created = True
|
||||
db.session.commit()
|
||||
return redirect(url_for('wallet.loading'))
|
||||
else:
|
||||
return redirect(url_for('wallet.dashboard'))
|
||||
return render_template(
|
||||
'wallet/setup.html',
|
||||
restore_form=restore_form
|
||||
)
|
||||
|
||||
@wallet_bp.route('/wallet/loading')
|
||||
@login_required
|
||||
def loading():
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, BooleanField
|
||||
from wtforms.validators import DataRequired
|
||||
from wtforms.validators import DataRequired, ValidationError
|
||||
|
||||
|
||||
class Register(FlaskForm):
|
||||
|
@ -20,3 +20,10 @@ class Send(FlaskForm):
|
|||
|
||||
class Delete(FlaskForm):
|
||||
confirm = BooleanField('Confirm Account and Wallet Deletion:', validators=[DataRequired()], render_kw={"class": "form-control-span"})
|
||||
|
||||
class Restore(FlaskForm):
|
||||
seed = StringField('Seed Phrase', validators=[DataRequired()], render_kw={"placeholder": "25 word mnemonic seed phrase", "class": "form-control"})
|
||||
|
||||
def validate_seed(self, seed):
|
||||
if len(self.seed.data.split()) != 25:
|
||||
raise ValidationError("Invalid seed provided; must be 25 word format")
|
||||
|
|
|
@ -19,21 +19,36 @@ class Docker(object):
|
|||
self.wallet_dir = expanduser(getattr(config, 'WALLET_DIR', '~/data/wallets'))
|
||||
self.listen_port = 8888
|
||||
|
||||
def create_wallet(self, user_id):
|
||||
def create_wallet(self, user_id, seed=None):
|
||||
u = User.query.get(user_id)
|
||||
volume_name = self.get_user_volume(u.id)
|
||||
u.wallet_password = token_urlsafe(12)
|
||||
db.session.commit()
|
||||
command = f"""wownero-wallet-cli \
|
||||
--generate-new-wallet /wallet/{u.id}.wallet \
|
||||
--restore-height {daemon.info()['height']} \
|
||||
--password {u.wallet_password} \
|
||||
--mnemonic-language English \
|
||||
--daemon-address {config.DAEMON_PROTO}://{config.DAEMON_HOST}:{config.DAEMON_PORT} \
|
||||
--daemon-login {config.DAEMON_USER}:{config.DAEMON_PASS} \
|
||||
--log-file /wallet/{u.id}-create.log
|
||||
--command version
|
||||
"""
|
||||
if seed:
|
||||
action = "restore"
|
||||
command = f"""sh -c "yes '' | wownero-wallet-cli \
|
||||
--restore-deterministic-wallet \
|
||||
--generate-new-wallet /wallet/{u.id}.wallet \
|
||||
--restore-height 0 \
|
||||
--password {u.wallet_password} \
|
||||
--daemon-address {config.DAEMON_PROTO}://{config.DAEMON_HOST}:{config.DAEMON_PORT} \
|
||||
--daemon-login {config.DAEMON_USER}:{config.DAEMON_PASS} \
|
||||
--electrum-seed '{seed}' \
|
||||
--log-file /wallet/{u.id}-{action}.log \
|
||||
--command refresh"
|
||||
"""
|
||||
else:
|
||||
action = "create"
|
||||
command = f"""wownero-wallet-cli \
|
||||
--generate-new-wallet /wallet/{u.id}.wallet \
|
||||
--restore-height {daemon.info()['height']} \
|
||||
--password {u.wallet_password} \
|
||||
--mnemonic-language English \
|
||||
--daemon-address {config.DAEMON_PROTO}://{config.DAEMON_HOST}:{config.DAEMON_PORT} \
|
||||
--daemon-login {config.DAEMON_USER}:{config.DAEMON_PASS} \
|
||||
--log-file /wallet/{u.id}-{action}.log \
|
||||
--command version
|
||||
"""
|
||||
if not self.volume_exists(volume_name):
|
||||
self.client.volumes.create(
|
||||
name=volume_name,
|
||||
|
@ -43,7 +58,7 @@ class Docker(object):
|
|||
self.wownero_image,
|
||||
command=command,
|
||||
auto_remove=True,
|
||||
name=f'create_wallet_{u.id}',
|
||||
name=f'{action}_wallet_{u.id}',
|
||||
remove=True,
|
||||
detach=True,
|
||||
volumes={
|
||||
|
@ -53,7 +68,7 @@ class Docker(object):
|
|||
}
|
||||
}
|
||||
)
|
||||
send_es({'type': 'create_wallet', 'user': u.email})
|
||||
send_es({'type': f'{action}_wallet', 'user': u.email})
|
||||
return container.short_id
|
||||
|
||||
def start_wallet(self, user_id):
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<div class="header-content mx-auto">
|
||||
<h1 class="mb-5">Manage your Wownero funds securely and anonymously.</h1>
|
||||
{% if current_user.is_authenticated %}
|
||||
<a href="{{ url_for('wallet.dashboard') }}" class="btn btn-outline btn-xl">{% if current_user.wallet_created %}Wallet Dashboard{% else %}Create Wallet{% endif %}</a>
|
||||
<a href="{{ url_for('wallet.setup') }}" class="btn btn-outline btn-xl">{% if current_user.wallet_created %}Wallet Dashboard{% else %}Setup Wallet{% endif %}</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('auth.register') }}" class="btn btn-outline btn-xl">Register</a>
|
||||
<a href="{{ url_for('auth.login') }}" class="btn btn-outline btn-xl">Login</a>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<li class="nav-item"><a class="nav-link" href="/#contact">Contact</a></li>
|
||||
{% endif %}
|
||||
{% if current_user.is_authenticated %}
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('wallet.dashboard') }}">Wallet</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('wallet.setup') }}">Wallet</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('auth.logout') }}">Logout</a></li>
|
||||
{% else %}
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('auth.login') }}">Login</a></li>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
{% else %}
|
||||
<h2>Your wallet is connecting</h2>
|
||||
{% endif %}
|
||||
<p>Go smoke a fatty. This page should auto-refresh when it's ready...if not, click the button below</p>
|
||||
<p>Go smoke a fatty. This page should auto-refresh when it's ready...if not, click the button below. <br /><br />If you are restoring from a seed, please allow several minutes for the process to complete.</p>
|
||||
<img src="/static/img/loading-cat.gif" width=300>
|
||||
<span class="dashboard-buttons">
|
||||
<div class="col-sm-12 dashboard-button">
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
{% include 'head.html' %}
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
{% include 'navbar.html' %}
|
||||
|
||||
<section class="section2">
|
||||
<div class="container">
|
||||
<div class="section-heading text-center">
|
||||
<h2>Pick An Option</h2>
|
||||
<p>Alrighty there hoss, pick an option below...</p>
|
||||
|
||||
<a class="btn btn-lg btn-link btn-outline btn-xl" href="{{ url_for('wallet.dashboard') }}">Create new wallet</a>
|
||||
|
||||
<hr><br /><br />
|
||||
|
||||
<form method="POST" action="{{ url_for('wallet.setup') }}" class="send-form">
|
||||
{{ restore_form.csrf_token }}
|
||||
{% for f in restore_form %}
|
||||
{% if f.name != 'csrf_token' %}
|
||||
<div class="form-group">
|
||||
{{ f.label }}
|
||||
{{ f }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<ul>
|
||||
{% for field, errors in restore_form.errors.items() %}
|
||||
<li>{{ restore_form[field].label }}: {{ ', '.join(errors) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<input type="submit" value="Restore From Seed" class="btn btn-link btn-outline btn-xl">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% include 'footer.html' %}
|
||||
|
||||
{% include 'scripts.html' %}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue