101 lines
2.1 KiB
Go
101 lines
2.1 KiB
Go
package analytics
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// AddressRiskAnalyzer analyzes address risk
|
|
type AddressRiskAnalyzer struct {
|
|
db *pgxpool.Pool
|
|
chainID int
|
|
}
|
|
|
|
// NewAddressRiskAnalyzer creates a new address risk analyzer
|
|
func NewAddressRiskAnalyzer(db *pgxpool.Pool, chainID int) *AddressRiskAnalyzer {
|
|
return &AddressRiskAnalyzer{
|
|
db: db,
|
|
chainID: chainID,
|
|
}
|
|
}
|
|
|
|
// RiskAnalysis represents address risk analysis
|
|
type RiskAnalysis struct {
|
|
Address string
|
|
RiskScore float64
|
|
RiskLevel string
|
|
Factors map[string]bool
|
|
Flags []string
|
|
}
|
|
|
|
// AnalyzeAddress analyzes risk for an address
|
|
func (ara *AddressRiskAnalyzer) AnalyzeAddress(ctx context.Context, address string) (*RiskAnalysis, error) {
|
|
// Get address statistics
|
|
query := `
|
|
SELECT
|
|
tx_count_sent,
|
|
tx_count_received,
|
|
total_sent_wei,
|
|
total_received_wei
|
|
FROM addresses
|
|
WHERE address = $1 AND chain_id = $2
|
|
`
|
|
|
|
var txSent, txReceived int
|
|
var totalSent, totalReceived string
|
|
err := ara.db.QueryRow(ctx, query, address, ara.chainID).Scan(&txSent, &txReceived, &totalSent, &totalReceived)
|
|
if err != nil {
|
|
// Address not found, return low risk
|
|
return &RiskAnalysis{
|
|
Address: address,
|
|
RiskScore: 0.0,
|
|
RiskLevel: "low",
|
|
Factors: make(map[string]bool),
|
|
Flags: []string{},
|
|
}, nil
|
|
}
|
|
|
|
// Calculate risk score (simplified)
|
|
riskScore := 0.0
|
|
factors := make(map[string]bool)
|
|
flags := []string{}
|
|
|
|
// High volume = lower risk
|
|
if txSent+txReceived > 100 {
|
|
factors["high_volume"] = true
|
|
riskScore -= 0.1
|
|
}
|
|
|
|
// Check for suspicious patterns (simplified)
|
|
if txSent > 1000 && txReceived == 0 {
|
|
factors["suspicious_activity"] = true
|
|
riskScore += 0.3
|
|
flags = append(flags, "high_outbound_only")
|
|
}
|
|
|
|
// Normalize risk score
|
|
if riskScore < 0 {
|
|
riskScore = 0
|
|
}
|
|
if riskScore > 1 {
|
|
riskScore = 1
|
|
}
|
|
|
|
riskLevel := "low"
|
|
if riskScore > 0.7 {
|
|
riskLevel = "high"
|
|
} else if riskScore > 0.4 {
|
|
riskLevel = "medium"
|
|
}
|
|
|
|
return &RiskAnalysis{
|
|
Address: address,
|
|
RiskScore: riskScore,
|
|
RiskLevel: riskLevel,
|
|
Factors: factors,
|
|
Flags: flags,
|
|
}, nil
|
|
}
|
|
|