mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-27 12:24:12 +00:00
130 lines
3.9 KiB
Go
130 lines
3.9 KiB
Go
package handler
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"math"
|
|
"net/http"
|
|
|
|
"github.com/debros/orama-website/invest-api/auth"
|
|
dbpkg "github.com/debros/orama-website/invest-api/db"
|
|
"github.com/debros/orama-website/invest-api/helius"
|
|
)
|
|
|
|
func AnchatBalanceHandler(database *sql.DB, heliusClient *helius.Client) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
wallet, chain, ok := auth.WalletFromContext(r.Context())
|
|
if !ok {
|
|
jsonError(w, http.StatusUnauthorized, "wallet required")
|
|
return
|
|
}
|
|
|
|
if chain != "sol" {
|
|
jsonError(w, http.StatusBadRequest, "$ANCHAT is a Solana token — connect with a Solana wallet")
|
|
return
|
|
}
|
|
|
|
// Check current claim status
|
|
var status string
|
|
err := database.QueryRow("SELECT status FROM anchat_claims WHERE wallet = ?", wallet).Scan(&status)
|
|
hasActiveClaim := err == nil && status == "active"
|
|
hasRevokedClaim := err == nil && status == "revoked"
|
|
|
|
balance, err := heliusClient.GetTokenBalance(wallet, dbpkg.AnchatMint)
|
|
if err != nil {
|
|
jsonError(w, http.StatusInternalServerError, fmt.Sprintf("failed to check $ANCHAT balance: %v", err))
|
|
return
|
|
}
|
|
|
|
claimable := 0.0
|
|
canClaim := false
|
|
if balance >= dbpkg.AnchatMinBalance && !hasActiveClaim {
|
|
claimable = math.Floor(balance * dbpkg.AnchatClaimRate)
|
|
canClaim = true
|
|
}
|
|
|
|
jsonResponse(w, http.StatusOK, map[string]any{
|
|
"balance": balance,
|
|
"claimable_orama": claimable,
|
|
"already_claimed": hasActiveClaim,
|
|
"was_revoked": hasRevokedClaim,
|
|
"can_claim": canClaim,
|
|
"min_balance": dbpkg.AnchatMinBalance,
|
|
})
|
|
}
|
|
}
|
|
|
|
func AnchatClaimHandler(database *sql.DB, heliusClient *helius.Client) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
wallet, chain, ok := auth.WalletFromContext(r.Context())
|
|
if !ok {
|
|
jsonError(w, http.StatusUnauthorized, "wallet required")
|
|
return
|
|
}
|
|
|
|
if chain != "sol" {
|
|
jsonError(w, http.StatusBadRequest, "$ANCHAT is a Solana token — connect with a Solana wallet")
|
|
return
|
|
}
|
|
|
|
// Check if there's an active claim already
|
|
var status string
|
|
err := database.QueryRow("SELECT status FROM anchat_claims WHERE wallet = ?", wallet).Scan(&status)
|
|
if err == nil && status == "active" {
|
|
jsonError(w, http.StatusConflict, "you already have an active $ORAMA claim")
|
|
return
|
|
}
|
|
|
|
// Fresh balance (bypass cache)
|
|
balance, err := heliusClient.GetTokenBalanceFresh(wallet, dbpkg.AnchatMint)
|
|
if err != nil {
|
|
jsonError(w, http.StatusInternalServerError, fmt.Sprintf("failed to verify $ANCHAT balance: %v", err))
|
|
return
|
|
}
|
|
|
|
if balance < dbpkg.AnchatMinBalance {
|
|
jsonError(w, http.StatusBadRequest,
|
|
fmt.Sprintf("minimum %s $ANCHAT required (you have %.0f)",
|
|
formatInt(dbpkg.AnchatMinBalance), balance))
|
|
return
|
|
}
|
|
|
|
oramaAmount := math.Floor(balance * dbpkg.AnchatClaimRate)
|
|
if oramaAmount <= 0 {
|
|
jsonError(w, http.StatusBadRequest, "$ANCHAT balance too low to claim $ORAMA")
|
|
return
|
|
}
|
|
|
|
// Upsert: if previously revoked, update to active; otherwise insert
|
|
_, err = database.Exec(`
|
|
INSERT INTO anchat_claims (wallet, anchat_balance_at_claim, orama_amount, status, flagged_at, warned_at, revoked_at)
|
|
VALUES (?, ?, ?, 'active', NULL, NULL, NULL)
|
|
ON CONFLICT(wallet) DO UPDATE SET
|
|
anchat_balance_at_claim = ?,
|
|
orama_amount = ?,
|
|
status = 'active',
|
|
flagged_at = NULL,
|
|
warned_at = NULL,
|
|
revoked_at = NULL,
|
|
claimed_at = CURRENT_TIMESTAMP
|
|
`, wallet, balance, oramaAmount, balance, oramaAmount)
|
|
if err != nil {
|
|
jsonError(w, http.StatusInternalServerError, "failed to record claim")
|
|
return
|
|
}
|
|
|
|
logActivity(database, "anchat_claim", wallet, fmt.Sprintf("%.0f $ANCHAT → %.0f $ORAMA", balance, oramaAmount))
|
|
|
|
jsonResponse(w, http.StatusCreated, map[string]any{
|
|
"orama_amount": oramaAmount,
|
|
})
|
|
}
|
|
}
|
|
|
|
func formatInt(n float64) string {
|
|
if n >= 1000 {
|
|
return fmt.Sprintf("%.0fK", n/1000)
|
|
}
|
|
return fmt.Sprintf("%.0f", n)
|
|
}
|