flask web app (wip)
This commit is contained in:
parent
b9410f2986
commit
49384accf6
@ -1463,7 +1463,13 @@ async def main():
|
||||
logging.info("Restarting wallet_watch_loop")
|
||||
await send_telegram_message("Restarting wallet_watch_loop")
|
||||
|
||||
|
||||
from modules.webui import init_app
|
||||
|
||||
async def run_flask():
|
||||
# loop = asyncio.get_running_loop()
|
||||
# await loop.run_in_executor(None, lambda: app.run(debug=False, port=3001, use_reloader=False))
|
||||
app = init_app()
|
||||
loop = asyncio.get_running_loop()
|
||||
await loop.run_in_executor(None, lambda: app.run(debug=False, port=3001, use_reloader=False))
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
from flask import Flask, jsonify, request
|
||||
from flask_login import LoginManager, UserMixin, login_user, login_required, current_user
|
||||
from flask import Flask, jsonify, request, render_template, redirect, url_for
|
||||
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
|
||||
import secrets
|
||||
from modules import storage # Import your storage module
|
||||
from modules import storage
|
||||
|
||||
app = Flask(__name__)
|
||||
app = Flask(__name__, template_folder='../templates', static_folder='../static')
|
||||
app.config['SECRET_KEY'] = 'your-secret-key'
|
||||
login_manager = LoginManager(app)
|
||||
login_manager.login_view = 'login'
|
||||
|
||||
class User(UserMixin):
|
||||
def __init__(self, id, username, email):
|
||||
@ -20,18 +21,34 @@ def load_user(user_id):
|
||||
return User(id=user_data['id'], username=user_data['username'], email=user_data['email'])
|
||||
return None
|
||||
|
||||
@app.route('/login', methods=['POST'])
|
||||
def login():
|
||||
data = request.json
|
||||
username = data.get('username')
|
||||
password = data.get('password')
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
user = storage.authenticate_user(username, password)
|
||||
if user:
|
||||
login_user(User(id=user['id'], username=user['username'], email=user['email']))
|
||||
return jsonify({'message': 'Login successful'}), 200
|
||||
else:
|
||||
return jsonify({'message': 'Invalid credentials'}), 401
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
|
||||
user = storage.authenticate_user(username, password)
|
||||
if user:
|
||||
login_user(User(id=user['id'], username=user['username'], email=user['email']))
|
||||
return redirect(url_for('dashboard'))
|
||||
else:
|
||||
return render_template('login.html', error='Invalid credentials')
|
||||
return render_template('login.html')
|
||||
|
||||
@app.route('/logout')
|
||||
@login_required
|
||||
def logout():
|
||||
logout_user()
|
||||
return redirect(url_for('index'))
|
||||
|
||||
@app.route('/dashboard')
|
||||
@login_required
|
||||
def dashboard():
|
||||
return render_template('dashboard.html')
|
||||
|
||||
@app.route('/generate_api_key', methods=['POST'])
|
||||
@login_required
|
||||
|
@ -2,6 +2,7 @@ aiohttp==3.10.9
|
||||
base58==2.1.1
|
||||
dexscreener==1.1
|
||||
Flask==3.0.3
|
||||
flask-login
|
||||
jupiter_python_sdk==0.0.2.0
|
||||
python-dotenv==1.0.1
|
||||
python-telegram-bot==21.6
|
||||
|
@ -0,0 +1,46 @@
|
||||
/* Add your custom styles here */
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: #4A90E2;
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul li {
|
||||
display: inline;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
nav ul li a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
/* Add responsive styles for mobile devices */
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
|
||||
document.getElementById('connectWallet').addEventListener('click', async () => {
|
||||
try {
|
||||
const { solana } is window;
|
||||
@ -26,3 +27,20 @@ document.getElementById('swapToken').addEventListener('click', () => {
|
||||
.then(response => response.json())
|
||||
.then(data => alert(data.message));
|
||||
});
|
||||
|
||||
|
||||
// Add your custom JavaScript here
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const generateApiKeyButton = document.getElementById('generate-api-key');
|
||||
const apiKeyDisplay = document.getElementById('api-key-display');
|
||||
|
||||
if (generateApiKeyButton) {
|
||||
generateApiKeyButton.addEventListener('click', async () => {
|
||||
const response = await fetch('/generate_api_key', { method: 'POST' });
|
||||
const data = await response.json();
|
||||
apiKeyDisplay.textContent = `Your API Key: ${data.api_key}`;
|
||||
});
|
||||
}
|
||||
|
||||
// Add more JavaScript for fetching and displaying wallet data, transactions, and holdings
|
||||
});
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "Crypto Portfolio Tracker",
|
||||
"short_name": "CryptoTracker",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#ffffff",
|
||||
"theme_color": "#4A90E2",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/static/images/logo-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/logo-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
// Add service worker code for offline functionality and caching
|
||||
self.addEventListener('install', (event) => {
|
||||
// Perform install steps
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
// Handle fetch events
|
||||
});
|
36
crypto/sol/templates/base.html
Normal file
36
crypto/sol/templates/base.html
Normal file
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}Crypto Portfolio Tracker{% endblock %}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
|
||||
<meta name="theme-color" content="#4A90E2">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="{{ url_for('index') }}">Home</a></li>
|
||||
{% if current_user.is_authenticated %}
|
||||
<li><a href="{{ url_for('dashboard') }}">Dashboard</a></li>
|
||||
<li><a href="{{ url_for('logout') }}">Logout</a></li>
|
||||
{% else %}
|
||||
<li><a href="{{ url_for('login') }}">Login</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2023 Crypto Portfolio Tracker</p>
|
||||
</footer>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
23
crypto/sol/templates/dashboard.html
Normal file
23
crypto/sol/templates/dashboard.html
Normal file
@ -0,0 +1,23 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Dashboard</h1>
|
||||
<p>Welcome, {{ current_user.username }}!</p>
|
||||
|
||||
<h2>Your Wallets</h2>
|
||||
<div id="wallets"></div>
|
||||
|
||||
<h2>Recent Transactions</h2>
|
||||
<div id="transactions"></div>
|
||||
|
||||
<h2>Holdings</h2>
|
||||
<div id="holdings"></div>
|
||||
|
||||
<button id="generate-api-key">Generate API Key</button>
|
||||
<p id="api-key-display"></p>
|
||||
|
||||
<script>
|
||||
// Add JavaScript to fetch and display wallet data, transactions, and holdings
|
||||
// Also add functionality for generating API key
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,21 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Token Swapper</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Token Swapper</h1>
|
||||
<div>
|
||||
<button id="connectWallet">Connect Phantom Wallet</button>
|
||||
</div>
|
||||
<div>
|
||||
<input type="text" id="tokenName" placeholder="Enter Token Name">
|
||||
<input type="number" id="amount" placeholder="Enter Amount">
|
||||
<button id="swapToken">Swap Token</button>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@solana/web3.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Welcome to Crypto Portfolio Tracker</h1>
|
||||
<p>Track your cryptocurrency investments with ease.</p>
|
||||
{% endblock %}
|
17
crypto/sol/templates/login.html
Normal file
17
crypto/sol/templates/login.html
Normal file
@ -0,0 +1,17 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Login</h1>
|
||||
<form method="POST" action="{{ url_for('login') }}">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
{% if error %}
|
||||
<p class="error">{{ error }}</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
21
crypto/sol/templates/swap.html
Normal file
21
crypto/sol/templates/swap.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Token Swapper</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Token Swapper</h1>
|
||||
<div>
|
||||
<button id="connectWallet">Connect Phantom Wallet</button>
|
||||
</div>
|
||||
<div>
|
||||
<input type="text" id="tokenName" placeholder="Enter Token Name">
|
||||
<input type="number" id="amount" placeholder="Enter Amount">
|
||||
<button id="swapToken">Swap Token</button>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@solana/web3.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user