Skip to content

feat:Implement Wallet Reputation Scoring#213

Open
OlufunbiIK wants to merge 1 commit into
MD-Creative-Production:mainfrom
OlufunbiIK:feat/Implement-Wallet-Reputation-Scoring
Open

feat:Implement Wallet Reputation Scoring#213
OlufunbiIK wants to merge 1 commit into
MD-Creative-Production:mainfrom
OlufunbiIK:feat/Implement-Wallet-Reputation-Scoring

Conversation

@OlufunbiIK

Copy link
Copy Markdown

feat(reputation): wallet trust scoring module

Summary

Implements a new reputation module that assigns a 0–100 trust score to monitored wallets, giving security teams context around the wallets they're investigating. Closes the linked issue.

Concept → Implementation mapping

Issue requirement Where it's implemented
Reputation calculation services/reputation-calculator.service.ts — weighted composite of 5 factors
Risk indicators services/risk-indicator.service.ts — sanctions/mixer/flagged-contract/incident detection
Historical analysis reputation.service.ts#getHistory + ReputationScore snapshots persisted per calculation
Scores generated ReputationService.recalculate()
Scores stored repository/reputation.repository.ts (Prisma) + prisma/reputation.prisma.snippet
Scores exposed via API reputation.controller.ts (3 endpoints, see below)

Scores map to four tiers: TRUSTED (75+), NEUTRAL (50+), SUSPICIOUS (25+), HIGH_RISK (<25). Every score is returned with a full breakdown and the list of RiskIndicators that produced it, so results are explainable rather than a black-box number — useful for analysts who need to justify a flag.

Scores are cached for 6 hours (REPUTATION_SCORE_TTL_MS) before a GET triggers a recalculation; a POST .../recalculate endpoint allows forcing a fresh calculation on demand.

API

GET  /reputation/:walletAddress?chainId=stellar          → current score
POST /reputation/:walletAddress/recalculate               → force recalculation
GET  /reputation/:walletAddress/history?chainId=&limit=&offset=  → paginated history
GET  /reputation/tier/:tier?chainId=&limit=                → wallets in a given trust tier

Integration points that need wiring before merge

This module was written without access to the real project source (only the file tree), so the boundaries to existing modules are implemented as small, swappable interfaces rather than hard imports:

  1. ChainDataProvider (reputation.service.ts) — currently StubChainDataProvider, returns empty activity. Replace with an adapter over chains/integrations that returns real first-seen date, tx counts, and counterparty addresses for a wallet.
  2. IncidentDataProvider (reputation.service.ts) — currently StubIncidentDataProvider. Replace with an adapter over cases/incidents returning open/resolved/confirmed-fraud counts for a wallet.
  3. SanctionsListProvider (services/risk-indicator.service.ts) — currently StubSanctionsListProvider, always returns "clean". Replace with the platform's real sanctioned/mixer/flagged-contract source, likely under behavioral-analysis.
  4. Persistencereputation.repository.ts assumes a PrismaService at src/database/prisma.service.ts and a DatabaseModule at src/database/database.module.ts, matching the database/ folder in the tree. If the project actually uses TypeORM, only reputation.repository.ts needs to change — its public method signatures are the contract the rest of the module relies on.
  5. Auth — the controller has a commented-out @UseGuards(ApiKeyGuard) pointing at api-keys/api-key.guard. Uncomment and fix the import path once confirmed.
  6. Schema — merge prisma/reputation.prisma.snippet into schema.prisma and run a migration (npx prisma migrate dev --name add_reputation_score).

Out of scope / follow-ups

  • Network-association scoring currently defaults to a neutral value; a real counterparty-graph walk (NETWORK_ANALYSIS_MAX_HOPS is already defined for this) is left as a follow-up once a graph/indexing source is identified.
  • No scheduled/background recalculation job yet — currently lazy (computed on read, cached via TTL). A cron-based refresh for HIGH_RISK wallets would be a reasonable next step.
  • No rate limiting on the recalculate endpoint beyond the TTL check on GET; consider throttling if this proves expensive against chain-data providers.

Testing

  • reputation.service.spec.ts unit-tests ReputationCalculatorService: weight sum sanity check, clean-wallet → TRUSTED, fraud-case → heavy penalty, extreme-inputs stay within [0, 100], no-data wallets scored neutrally rather than punitively.
  • Ran a standalone tsc --noEmit pass against the new files to confirm there are no type errors beyond expected missing-module errors for packages not installed in this sandbox (@nestjs/common, class-validator, class-transformer, Prisma client) — these will resolve once the files land in the real repo.
  • Not yet run against a live database/chain-data source (blocked on integration points above).

How to review

Start with reputation-calculator.service.ts for the scoring math, then risk-indicator.service.ts for what gets detected, then reputation.service.ts to see how they're composed and cached. The controller and DTOs are thin by design.

Closes #124

@mijinummi

Copy link
Copy Markdown
Collaborator

Hi @OlufunbiIK please kindly look into this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Wallet Reputation Scoring

2 participants