chore: remove solana wallet stack
This commit is contained in:
+29
-210
@@ -1,223 +1,42 @@
|
||||
import crypto from "crypto";
|
||||
import { Router } from "express";
|
||||
import {
|
||||
type AuthenticatedRequest,
|
||||
authenticate,
|
||||
requireAdmin,
|
||||
} from "../middleware/auth";
|
||||
import { type AuthenticatedRequest, authenticate, requireAdmin } from "../middleware/auth";
|
||||
import { asyncHandler } from "../middleware/errorHandler";
|
||||
import { createWallet } from "../services/solana";
|
||||
import { prisma } from "../utils/prisma";
|
||||
|
||||
const router = Router();
|
||||
const ENCRYPTION_KEY =
|
||||
process.env.ENCRYPTION_KEY || "default-key-32-chars-long!!!!!";
|
||||
|
||||
function encrypt(text: string): string {
|
||||
const iv = crypto.randomBytes(16);
|
||||
const key = crypto.createHash("sha256").update(ENCRYPTION_KEY).digest();
|
||||
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
|
||||
let encrypted = cipher.update(text, "utf8", "hex");
|
||||
encrypted += cipher.final("hex");
|
||||
const authTag = cipher.getAuthTag();
|
||||
return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}`;
|
||||
}
|
||||
router.get("/", authenticate, asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const user = await prisma.user.findUnique({ where: { id: req.user!.id }, select: { totalEarned: true, totalSpent: true } });
|
||||
res.json({ hasWallet: false, balance: (user?.totalEarned || 0) - (user?.totalSpent || 0), totalEarned: user?.totalEarned || 0, totalSpent: user?.totalSpent || 0 });
|
||||
}));
|
||||
|
||||
function decrypt(encryptedData: string): string {
|
||||
const parts = encryptedData.split(":");
|
||||
const iv = Buffer.from(parts[0], "hex");
|
||||
const authTag = Buffer.from(parts[1], "hex");
|
||||
const encrypted = parts[2];
|
||||
const key = crypto.createHash("sha256").update(ENCRYPTION_KEY).digest();
|
||||
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
|
||||
decipher.setAuthTag(authTag);
|
||||
let decrypted = decipher.update(encrypted, "hex", "utf8");
|
||||
decrypted += decipher.final("utf8");
|
||||
return decrypted;
|
||||
}
|
||||
router.post("/create", authenticate, asyncHandler(async (_req: AuthenticatedRequest, res) => {
|
||||
res.status(410).json({ error: "Wallets removed" });
|
||||
}));
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
authenticate,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: req.user!.id },
|
||||
select: {
|
||||
walletAddress: true,
|
||||
totalEarned: true,
|
||||
totalSpent: true,
|
||||
},
|
||||
});
|
||||
router.post("/connect", authenticate, asyncHandler(async (_req: AuthenticatedRequest, res) => {
|
||||
res.status(410).json({ error: "Wallets removed" });
|
||||
}));
|
||||
|
||||
if (!user?.walletAddress) {
|
||||
return res.json({
|
||||
hasWallet: false,
|
||||
balance: 0,
|
||||
totalEarned: user?.totalEarned || 0,
|
||||
totalSpent: user?.totalSpent || 0,
|
||||
});
|
||||
}
|
||||
router.post("/backup", authenticate, asyncHandler(async (_req: AuthenticatedRequest, res) => {
|
||||
res.status(410).json({ error: "Wallets removed" });
|
||||
}));
|
||||
|
||||
const dbBalance = user.totalEarned - user.totalSpent;
|
||||
router.get("/admin/:userId", authenticate, requireAdmin, asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const user = await prisma.user.findUnique({ where: { id: req.params.userId }, select: { id: true, plexUsername: true, email: true, isAdmin: true, isActive: true, totalEarned: true, totalSpent: true, watchTimeMinutes: true, createdAt: true } });
|
||||
if (!user) return res.status(404).json({ error: "User not found" });
|
||||
res.json({ ...user, balance: user.totalEarned - user.totalSpent });
|
||||
}));
|
||||
|
||||
res.json({
|
||||
hasWallet: true,
|
||||
address: user.walletAddress,
|
||||
balance: dbBalance,
|
||||
totalEarned: user.totalEarned,
|
||||
totalSpent: user.totalSpent,
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/create",
|
||||
authenticate,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: req.user!.id },
|
||||
});
|
||||
|
||||
if (user?.walletAddress) {
|
||||
return res.status(400).json({ error: "Wallet already exists" });
|
||||
}
|
||||
|
||||
const wallet = createWallet();
|
||||
const encryptedKey = encrypt(wallet.secretKey);
|
||||
|
||||
await prisma.user.update({
|
||||
where: { id: req.user!.id },
|
||||
data: {
|
||||
walletAddress: wallet.publicKey,
|
||||
encryptedPrivateKey: encryptedKey,
|
||||
},
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
address: wallet.publicKey,
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/connect",
|
||||
authenticate,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const { address } = req.body;
|
||||
|
||||
if (!address) {
|
||||
return res.status(400).json({ error: "Address required" });
|
||||
}
|
||||
|
||||
const existing = await prisma.user.findFirst({
|
||||
where: { walletAddress: address },
|
||||
});
|
||||
|
||||
if (existing && existing.id !== req.user!.id) {
|
||||
return res.status(400).json({ error: "Wallet already in use" });
|
||||
}
|
||||
|
||||
await prisma.user.update({
|
||||
where: { id: req.user!.id },
|
||||
data: { walletAddress: address },
|
||||
});
|
||||
|
||||
res.json({ success: true, address });
|
||||
}),
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/backup",
|
||||
authenticate,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: req.user!.id },
|
||||
});
|
||||
|
||||
if (!user?.encryptedPrivateKey) {
|
||||
return res.status(400).json({ error: "No wallet backup available" });
|
||||
}
|
||||
|
||||
const privateKey = decrypt(user.encryptedPrivateKey);
|
||||
res.json({ success: true, privateKey });
|
||||
}),
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/admin/:userId",
|
||||
authenticate,
|
||||
requireAdmin,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: req.params.userId },
|
||||
select: {
|
||||
id: true,
|
||||
plexUsername: true,
|
||||
email: true,
|
||||
isAdmin: true,
|
||||
isActive: true,
|
||||
walletAddress: true,
|
||||
totalEarned: true,
|
||||
totalSpent: true,
|
||||
watchTimeMinutes: true,
|
||||
createdAt: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({ error: "User not found" });
|
||||
}
|
||||
|
||||
res.json({
|
||||
...user,
|
||||
balance: user.totalEarned - user.totalSpent,
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/admin/:userId/adjust",
|
||||
authenticate,
|
||||
requireAdmin,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const { amount, reason } = req.body;
|
||||
|
||||
if (!amount || Number.isNaN(Number(amount)) || Number(amount) === 0) {
|
||||
return res.status(400).json({ error: "Valid amount required" });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: req.params.userId },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({ error: "User not found" });
|
||||
}
|
||||
|
||||
const delta = Number(amount);
|
||||
const type = delta > 0 ? "BONUS" : "ADJUSTMENT";
|
||||
|
||||
await prisma.transaction.create({
|
||||
data: {
|
||||
userId: user.id,
|
||||
type,
|
||||
amount: Math.abs(delta),
|
||||
description: reason || "Admin adjustment",
|
||||
contentTitle: reason || "Admin adjustment",
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.user.update({
|
||||
where: { id: user.id },
|
||||
data: {
|
||||
totalEarned: delta > 0 ? { increment: delta } : undefined,
|
||||
totalSpent: delta < 0 ? { increment: Math.abs(delta) } : undefined,
|
||||
},
|
||||
});
|
||||
|
||||
res.json({ success: true });
|
||||
}),
|
||||
);
|
||||
router.post("/admin/:userId/adjust", authenticate, requireAdmin, asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const { amount, reason } = req.body;
|
||||
if (!amount || Number.isNaN(Number(amount)) || Number(amount) === 0) return res.status(400).json({ error: "Valid amount required" });
|
||||
const user = await prisma.user.findUnique({ where: { id: req.params.userId } });
|
||||
if (!user) return res.status(404).json({ error: "User not found" });
|
||||
const delta = Number(amount);
|
||||
await prisma.transaction.create({ data: { userId: user.id, type: "ADJUSTMENT", amount: Math.abs(delta), description: reason || "Admin adjustment", contentTitle: reason || "Admin adjustment" } });
|
||||
await prisma.user.update({ where: { id: user.id }, data: delta > 0 ? { totalEarned: { increment: delta } } : { totalSpent: { increment: Math.abs(delta) } } });
|
||||
res.json({ success: true });
|
||||
}));
|
||||
|
||||
export { router as walletRouter };
|
||||
|
||||
Reference in New Issue
Block a user