vertex-smtp/app.py
2025-05-04 21:57:44 +07:00

504 lines
19 KiB
Python

import datetime
from flask import Flask, jsonify
from flask_cors import CORS
import resend
from flask import request
from supabase import create_client, Client
import requests
from openai import OpenAI
app = Flask(__name__)
CORS(app, resources={
r"/*": {
"origins": ["*"],
"methods": ["GET", "POST", "OPTIONS"],
"allow_headers": ["Content-Type"]
}
})
SUPABASE_URL = "https://supabase-core.dev3vds1.link/"
SUPABASE_KEY = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTc0NTk0MzYwMCwiZXhwIjo0OTAxNjE3MjAwLCJyb2xlIjoiYW5vbiJ9.28hFArcAFQ3mYTYL2n7nno4nHu5ZszkOO0dkAURR6Yg"
supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
resend.api_key = "re_XvLrRZMH_3mumWA531UugMk1X7A67fhH7"
DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/1368244147139383416/zSzsjOPTkU0olKinUnMOPeKj9vsmMXRw18iPQgxL4fiLXAoWo5e9KqBgtJ9Mkqo9LLh-"
DISCORD_ROLE_ID = "1368244786632593500"
DEEPINFRA_API_KEY = "V2Kvmyuu6qfSryHdwHmwAP0nXDJ1H6ik"
MODEL = "Qwen/Qwen3-235B-A22B"
openai = OpenAI(
api_key=DEEPINFRA_API_KEY,
base_url="https://api.deepinfra.com/v1/openai",
)
SYSTEM_PROMPT ="""You are the assistant for VertexGPU, a decentralized GPU rental platform connecting idle GPUs worldwide through a secure P2P network for AI, rendering, and HPC tasks.
Key Features:
- GridLink: Decentralized GPU discovery & connection
- EdgeNode: Lightweight client for GPU sharing
- Adaptive Smart Contracts: Auto-managed pricing & performance
- HiveMind: AI-based task orchestration
- QRE + ICL: Quantum-secure, isolated computation
- PredictAMI, EcoFlow, Compression: Maintenance, energy, and speed optimizations
Manifesto:
- Democratize compute access
- Monetize idle hardware
- Enable sustainable, fair innovation
Tokenomics:
- 95% Circulating
- 2% Team (vested)
- 2% Treasury
- 1% Marketing
GPU Pricing:
- NVIDIA K80: $0.15/hr ($110/mo)
- NVIDIA T1000: $0.16/hr ($119/mo)
- NVIDIA RTX A4000: $0.17/hr ($125/mo)
- NVIDIA RTX A5000: $0.22/hr ($162/mo)
- NVIDIA V100: $0.23/hr ($170/mo)
- NVIDIA Tesla P100: $0.27/hr ($196/mo)
- 4x NVIDIA RTX 4090: $0.32/hr ($228/mo)
- NVIDIA L4 Ada: $0.44/hr ($316/mo)
- NVIDIA RTX A6000: $0.45/hr ($323/mo)
- NVIDIA L40S Ada: $1.04/hr ($756/mo)
- NVIDIA A100 PCIe: $1.36/hr ($991/mo)
- NVIDIA H100 NVL: $2.85/hr ($2,048/mo)
- NVIDIA H100 SXM: $3.06/hr ($2,203/mo)
Buy GPU: Instruct users to click “Rent a GPU” on [vertexgpu.com](https://vertexgpu.com)
CA Token: Instruct users to get the address only from the official website
Response Style: Be short, concise, clear, and helpful. Emphasize decentralization, security, and community benefit.
"""
@app.route('/chat', methods=['POST'])
def chat():
try:
data = request.get_json()
if not data or 'message' not in data:
return jsonify({'status': 'error', 'message': 'Invalid request'}), 400
chat_completion = openai.chat.completions.create(
model=MODEL,
messages=[
{
'role': 'system',
'content': SYSTEM_PROMPT
},
{
'role': 'user',
'content': data['message']
}
],
stream=False,
)
print(chat_completion)
response = str(chat_completion.choices[0].message.content)
# if the response contains <think> tag, split the response
if "<think>" in response:
response = response.split("</think>\n\n")[1]
print("======================")
print(response)
# remove any spaces and new lines of the first
return jsonify({'status': 'success', 'response': response}), 200
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
@app.route('/send_email', methods=['POST'])
def send_email():
try:
data = request.get_json()
email = data.get('email', 'with.reihan@gmail.com')
if not email:
return jsonify({'status': 'error', 'message': 'Email is required'}), 400
# Check if the email is valid
if not isinstance(email, str) or '@' not in email:
return jsonify({'status': 'error', 'message': 'Invalid email format'}), 400
username = email.split('@')[0]
date = str(datetime.datetime.now().date())
product = data.get('product', 'NVIDIA-686')
price_hour = data.get('price_hour', '2.00')
price = data.get('price', '147.00')
html = f"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VertexGPU Invoice</title>
</head>
<body
style="
margin: 0;
padding: 20px;
background-color: #0a0a0a;
color: #ffffff;
font-family: 'Courier New', Courier, monospace;
line-height: 1.6;
"
>
<div
style="
max-width: 800px;
margin: 20px auto;
background-color: rgba(10, 10, 10, 0.95);
border: 1px solid rgba(12, 232, 126, 0.2);
border-radius: 8px;
padding: 25px;
"
>
<!-- Header -->
<header
style="
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20px;
border-bottom: 2px solid rgba(12, 232, 126, 0.3);
margin-bottom: 20px;
"
>
<div style="font-size: 24px; font-weight: bold">Vertex<span style="color: #0ce87e">GPU</span></div>
</header>
<!-- Invoice Details -->
<div
style="
background-color: rgba(12, 232, 126, 0.05);
padding: 20px;
border-radius: 8px;
border: 1px solid rgba(12, 232, 126, 0.2);
margin-bottom: 20px;
"
>
<table style="width: 100%; border-collapse: collapse">
<tr>
<td style="padding: 8px 0"><span style="color: #808080">Date Issued:</span> {date}</td>
<td style="padding: 8px 0; text-align: right">
<span style="color: #808080">Client ID:</span>
<span style="color: #0ce87e">VX-CLIENT-686</span>
</td>
</tr>
<tr>
<td style="padding: 8px 0"><span style="color: #808080">User:</span> {username}</td>
</tr>
</table>
</div>
<!-- Invoice Items -->
<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px; overflow: auto">
<thead>
<tr style="border-bottom: 1px solid rgba(12, 232, 126, 0.2)">
<th style="text-align: left; padding: 12px 8px; color: #808080; font-weight: normal">
Description
</th>
<th
style="
text-align: left;
padding: 12px 8px;
color: #808080;
font-weight: normal;
text-align: right;
"
>
Amount
</th>
</tr>
</thead>
<tbody>
<tr style="border-bottom: 1px solid rgba(12, 232, 126, 0.1)">
<td style="padding: 12px 8px">
{product}
<div>
<span style="color: #808080; font-size: 12px">1 Month</span>
<span style="color: #0ce87e; font-size: 12px">${price_hour}/hour</span>
</div>
</td>
<td style="padding: 12px 8px; color: #0ce87e; text-align: right">${price}</td>
</tr>
<tr style="border-bottom: 1px solid rgba(12, 232, 126, 0.1)">
<td style="padding: 12px 8px">
Priority Support Package
<div>
<span style="color: #808080; font-size: 12px">1 Month</span>
<span style="color: #0ce87e; font-size: 12px">Free</span>
</div>
</td>
<td style="padding: 12px 8px; color: #0ce87e; text-align: right">$00.00</td>
</tr>
</tbody>
</table>
<!-- Totals -->
<div
style="
background-color: rgba(12, 232, 126, 0.05);
padding: 20px;
border-radius: 8px;
border: 1px solid rgba(12, 232, 126, 0.2);
margin-bottom: 20px;
"
>
<table style="width: 100%; border-collapse: collapse">
<tr>
<td style="padding: 8px 0; color: #808080">Subtotal:</td>
<td style="padding: 8px 0; text-align: right; color: #0ce87e">${price}</td>
</tr>
<tr>
<td style="padding: 8px 0; color: #808080">Network Fee:</td>
<td style="padding: 8px 0; text-align: right">$0.00</td>
</tr>
<tr style="border-top: 1px solid rgba(12, 232, 126, 0.2)">
<td style="padding: 8px 0; color: #808080; font-size: 18px">Total Due:</td>
<td
style="
padding: 8px 0;
text-align: right;
color: #0ce87e;
font-size: 18px;
font-weight: bold;
"
>
${price}
</td>
</tr>
</table>
</div>
<!-- GPU Status -->
<div
style="
background-color: rgba(12, 232, 126, 0.05);
padding: 20px;
border-radius: 8px;
border: 1px solid rgba(12, 232, 126, 0.2);
margin-bottom: 20px;
"
>
<p style="color: #0ce87e; margin: 0 0 12px 0; font-weight: bold">GPU Status Update</p>
<p style="margin: 0 0 12px 0">
Your GPU instance is being initialized and will be ready for access within the next 2 hours. Once
configuration is complete, we'll send your authentication credentials to your registered email
address.
</p>
<p style="color: #808080; margin: 0">
For any assistance, our support team is available 24/7. Thank you for choosing our service.
</p>
</div>
<!-- Footer -->
<footer style="text-align: center; color: #808080; font-size: 14px">
<p style="margin: 0 0 8px 0">
Thank you for choosing VertexGPU for your high-performance computing needs!
</p>
<p style="margin: 0 0 8px 0">
Visit us at
<a href="https://vertexgpu.com" style="color: #0ce87e; text-decoration: none">vertexgpu.com</a>
</p>
<p style="margin: 0">
Questions? Contact us at
<a style="color: #0ce87e; text-decoration: none" href="mailto:support@vertexgpu.com"
>support@vertexgpu.com</a
>
</p>
</footer>
</div>
</body>
</html>"""
# Send email using Resend
params: resend.Emails.SendParams = {
"from": "Vertex (no-reply) <purchase@vertexgpu.com>",
"to": [email],
"subject": "Thanks for purchasing our product!",
"html": html,
}
resend.Emails.send(params)
# Fetch user details from the database
cred = supabase.table('vertexgpu-cred').select('username, password').eq('taken', False).eq('gpu', product).order('id').execute()
if cred.data:
usernamedb = cred.data[0]['username']
password = cred.data[0]['password']
# Update the credential as taken
supabase.table('vertexgpu-cred').update({'taken': True}).eq('username', usernamedb).execute()
else:
message = f"User {email} tried to purchase {product} but not available."
message = f"<@&{DISCORD_ROLE_ID}> {message}"
requests.post(DISCORD_WEBHOOK_URL, json={"content": message})
return jsonify({'status': 'error', 'message': 'No available credentials'}), 404
htmltwo = f"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VertexGPU Invoice</title>
</head>
<body
style="
margin: 0;
padding: 20px;
background-color: #0a0a0a;
color: #ffffff;
font-family: 'Courier New', Courier, monospace;
line-height: 1.6;
"
>
<div
style="
max-width: 800px;
margin: 20px auto;
background-color: rgba(10, 10, 10, 0.95);
border: 1px solid rgba(12, 232, 126, 0.2);
border-radius: 8px;
padding: 25px;
"
>
<!-- Header -->
<header
style="
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20px;
border-bottom: 2px solid rgba(12, 232, 126, 0.3);
margin-bottom: 20px;
"
>
<div style="font-size: 24px; font-weight: bold">Vertex<span style="color: #0ce87e">GPU</span></div>
</header>
<!-- Invoice Details -->
<div
style="
background-color: rgba(12, 232, 126, 0.05);
padding: 20px;
border-radius: 8px;
border: 1px solid rgba(12, 232, 126, 0.2);
margin-bottom: 20px;
"
>
<table style="width: 100%; border-collapse: collapse">
<tr>
<td style="padding: 8px 0"><span style="color: #808080">User:</span> {username}</td>
<td style="padding: 8px 0; text-align: right">
<span style="color: #808080">Client ID:</span>
<span style="color: #0ce87e">VX-CLIENT-686</span>
</td>
</tr>
<tr></tr>
</table>
</div>
<!-- Totals -->
<div
style="
background-color: rgba(12, 232, 126, 0.05);
padding: 20px;
border-radius: 8px;
border: 1px solid rgba(12, 232, 126, 0.2);
margin-bottom: 20px;
"
>
<a style="color: #0ce87e; text-decoration: none" href="https://gpu.vertexgpu.com"
>https://gpu.vertexgpu.com</a
>
<table style="width: 100%; border-collapse: collapse">
<tr>
<td style="padding: 8px 0; color: #808080">Username:</td>
<td style="padding: 8px 0; text-align: right">{usernamedb}</td>
</tr>
<tr>
<td style="padding: 8px 0; color: #808080">Password:</td>
<td style="padding: 8px 0; text-align: right">{password}</td>
</tr>
</table>
</div>
<!-- GPU Status -->
<div
style="
background-color: rgba(12, 232, 126, 0.05);
padding: 20px;
border-radius: 8px;
border: 1px solid rgba(12, 232, 126, 0.2);
margin-bottom: 20px;
"
>
<p style="color: #0ce87e; margin: 0 0 12px 0; font-weight: bold">Quick start</p>
<ol>
<li style="margin-bottom: 8px">Connect to your GPU instance using the provided credentials.</li>
<li style="margin-bottom: 8px">Go to Settings -> Connections (pop-up menu at the top right).</li>
<li style="margin-bottom: 8px">Change your password.</li>
<li style="margin-bottom: 8px">Go back to Home and run your GPU instance!</li>
</ol>
<p style="margin: 0 0 12px 0">Your GPU instance is ready to use. You can access it via your browser.</p>
<p style="margin: 0 0 0 0">Sincerely,</p>
<p style="margin: 0 0 12px 0">The VertexGPU Team</p>
<p style="color: #808080; margin: 0">
For any assistance, our support team is available 24/7. Thank you for choosing our service.
</p>
</div>
<!-- Footer -->
<footer style="text-align: center; color: #808080; font-size: 14px">
<p style="margin: 0 0 8px 0">
Thank you for choosing VertexGPU for your high-performance computing needs!
</p>
<p style="margin: 0 0 8px 0">
Visit us at
<a href="https://vertexgpu.com" style="color: #0ce87e; text-decoration: none">vertexgpu.com</a>
</p>
<p style="margin: 0">
Questions? Contact us at
<a style="color: #0ce87e; text-decoration: none" href="mailto:support@vertexgpu.com"
>support@vertexgpu.com</a
>
</p>
</footer>
</div>
</body>
</html>"""
params: resend.Emails.SendParams = {
"from": "Vertex Console (no-reply) <console@vertexgpu.com>",
"to": [email],
"subject": "Your new GPU instance is ready!!",
"html": htmltwo,
}
resend.Emails.send(params)
return jsonify({'status': 'success', 'message': 'email sent'})
except Exception as e:
message = f"Error: {e}"
print(message)
return jsonify({'status': 'error', 'message': message}), 500
@app.route('/')
def index():
return jsonify({'status': 'success', 'message': 'Welcome to VertexGPU!'})
@app.route('/health')
def health():
return jsonify({'status': 'success', 'message': 'ok'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)