fix(balance): use database credits instead of on-chain balance

Balance checks were reading on-chain Solana token balance (0
during db-only mode). Now wallet and overseer routes return
user.totalEarned - user.totalSpent as the usable credit balance.
This makes credits spendable even when devnet faucet is dry.

- /wallet returns dbBalance, with onChainBalance as extra info
- /overseer/balance returns dbBalance for request eligibility
- /overseer/request checks dbBalance before approving spend
- /wallet/admin returns dbBalance
This commit is contained in:
2026-04-21 15:37:06 -04:00
parent 5dbee115ad
commit fee4d8ce1b
2 changed files with 185 additions and 181 deletions
+8 -8
View File
@@ -65,13 +65,16 @@ router.get(
});
}
// Get on-chain balance
const balance = await getTokenBalance(user.walletAddress);
// Get on-chain balance (may be 0 if using DB-only credits)
const onChainBalance = await getTokenBalance(user.walletAddress);
// Usable credits are tracked in DB (works even when blockchain is down)
const dbBalance = user.totalEarned - user.totalSpent;
res.json({
hasWallet: true,
address: user.walletAddress,
balance,
balance: dbBalance,
onChainBalance,
totalEarned: user.totalEarned,
totalSpent: user.totalSpent,
explorerUrl: `https://explorer.solana.com/address/${user.walletAddress}?cluster=devnet`,
@@ -198,14 +201,11 @@ router.get(
return res.status(404).json({ error: "User not found" });
}
let balance = 0;
if (user.walletAddress) {
balance = await getTokenBalance(user.walletAddress);
}
const dbBalance = user.totalEarned - user.totalSpent;
res.json({
...user,
balance,
balance: dbBalance,
});
}),
);