FairScale

TypeScript SDK

Official TypeScript/JavaScript SDK for FairScale — trust scores, credit assessments, and agent directory.

TypeScript SDK

A minimal, zero-dependency client for both FairScale APIs — the Agent & Credit API (agent-api.fairscale.xyz) and the Human Score API (api.fairscale.xyz).

Installation

npm install @fairscale/sdk
# or
pnpm add @fairscale/sdk
# or
yarn add @fairscale/sdk

Initialisation

import { FairScale } from "@fairscale/sdk";

const client = new FairScale({
  apiKey: process.env.FAIRSCALE_API_KEY,       // Required (or use x402 per-request)
  baseUrl:      "https://agent-api.fairscale.xyz", // Agent & Credit API (default)
  humanBaseUrl: "https://api.fairscale.xyz",       // Human Score API (default)
  timeout: 10_000,                                 // ms, default 10 000
});

The SDK exposes three namespaces:

NamespaceHostUse for
client.* (root)agent-api.fairscale.xyzAgents, trust scoring, credit, directory
client.human.*api.fairscale.xyzHuman wallet scoring, features, badges
client.insights.*— (client-side)Derive pillars & humanity index from data

Trust Scoring

score(wallet, options?)

Returns a 0–100 composite trust score with pillar breakdown, badges, and red flags.

const result = await client.score("WALLET_ADDRESS");
console.log(result.score); // 67
console.log(result.tier);  // "silver"

// Optional task context for agent-specific scoring
const result = await client.score("WALLET_ADDRESS", {
  task: "defi_execution", // defi_execution | trust_focused | work_focused | hiring
});

Response shape:

{
  "wallet": "FRGumQszUGLTtfgH3gDwzG256pL4P8Cj3DDGAPCmBFka",
  "score": 67,
  "tier": "silver",
  "recommendation": { "tier": "trusted", "label": "Trusted", "color": "green" },
  "pillars": {
    "verification": 82,
    "wallet_history": 79,
    "work_history": 34,
    "network_quality": 71,
    "peer_reputation": 45
  },
  "signals": { "is_registered": true, "is_verified": true, "attestations": 3 },
  "red_flags": [],
  "badges": [{ "id": "verified_agent", "label": "Verified Agent", "tier": "gold" }],
  "meta": { "scored_at": "2026-04-07T12:00:00Z", "from_cache": false, "provider": "FairScale" }
}

scoreBatch(wallets, options?)

Score up to 25 wallets in one request.

const batch = await client.scoreBatch(["WALLET_1", "WALLET_2", "WALLET_3"]);

batch.results.forEach((r) => {
  if (r.error) return console.warn(r.wallet, r.error);
  console.log(r.wallet, r.score, r.tier);
});

Response shape:

{
  "total": 3,
  "scored": 3,
  "results": [ { "wallet": "...", "score": 72, "tier": "gold", "pillars": {...} } ],
  "meta": { "provider": "FairScale", "scored_at": "2026-04-07T12:00:00Z" }
}

scoreAI(wallet, options)

Composable score with adjustable pillar weights. Use a preset or supply your own weights.

// Preset (recommended)
const result = await client.scoreAI("WALLET_ADDRESS", {
  preset: "defi", // default | trust_focused | work_focused | defi | hiring
});

// Custom weights (must sum to 1.0 ± 0.02)
const result = await client.scoreAI("WALLET_ADDRESS", {
  weights: {
    verification:    0.40,
    wallet_history:  0.20,
    work_history:    0.20,
    network_quality: 0.10,
    peer_reputation: 0.10,
  },
});

Available presets:

Presetverificationwallet_historywork_historynetwork_qualitypeer_reputation
default0.300.250.100.250.10
trust_focused0.500.200.100.100.10
work_focused0.200.150.400.150.10
defi0.250.300.100.250.10
hiring0.350.150.250.150.10

Trust Gate

Binary allow/deny decision. The simplest integration for access control.

trustGate(wallet, options?)

const gate = await client.trustGate("WALLET_ADDRESS", {
  minScore:           40,              // Default 40. Minimum to pass.
  requireVerification: true,           // Optional. Requires registry presence.
  task:               "defi_execution",// Optional. Scoring context.
});

if (gate.allowed) {
  // proceed
} else {
  // deny — gate.score and gate.reason explain why
}

Response:

{
  "wallet": "WALLET_ADDRESS",
  "allowed": true,
  "score": 67,
  "reason": "score_above_threshold",
  "meta": { "from_cache": false, "provider": "FairScale" }
}

Agent Profile

agent(wallet)

Full agent profile including all scoring data, registry details, and trust signals.

const profile = await client.agent("WALLET_ADDRESS");

Score History

scoreHistory(wallet)

Score trend over time. Use for monitoring, trend charts, or detecting sudden drops.

const history = await client.scoreHistory("WALLET_ADDRESS");

Agent Directory

directory(options?)

Query the indexed agent directory with filtering and sorting.

const agents = await client.directory({
  page:        1,
  limit:       25,
  sort:        "agent_fairscore",  // See sort fields below
  minScore:    60,
  verifiedOnly: true,
  recommendation: "trusted",       // trusted | caution | high_risk | unverified
  source:      "said",             // said | erc8004 | sati
  search:      "DeFi",
  hasAttestations: true,
});

Available sort fields: agent_fairscore, verification, wallet_history, work_history, network_quality, peer_reputation, reliability, track_record, economic_stake, ecosystem

leaderboard(options?)

Top-scoring agents.

const top = await client.leaderboard({
  metric: "agent_fairscore", // any sort field
  limit:  25,
});

Credit Assessment

credit(wallet, options?)

Full credit assessment with underwriting opinion, risk flags, and recommended lending terms. Costs $0.50 USDC via x402 (or deducted from your plan).

const credit = await client.credit("WALLET_ADDRESS", {
  amount:  5000,   // Loan amount in USD (default: 1000)
  nocache: false,  // Set true to bypass 15-min cache
});

console.log(credit.credit_score);       // 68
console.log(credit.risk_band);          // "near_prime"
console.log(credit.underwriting.opinion);  // Full analyst narrative
console.log(credit.underwriting.lending_terms.suggested_apr_range); // { low: 7, high: 14 }
console.log(credit.underwriting.risk_flags); // [ { type: "positive", signal: "..." } ]

Risk bands:

BandScoreMeaning
prime75–100Eligible for unsecured credit
near_prime60–74Moderate collateral recommended
subprime45–59Full collateral, short terms
deep_subprime25–44Over-collateralised only
decline0–24Decline recommended

Human Score

Methods on client.human.* target api.fairscale.xyz — the Human Score API. This is the wallet-behaviour scoring surface (as opposed to the agent-reputation surface on the root namespace).

human.getScore(wallet, options?)

Full human wallet analysis — score, tier, badges, actions, humanity signal, and the 15-feature on-chain fingerprint. Cache-first (15 min).

const result = await client.human.getScore("WALLET_ADDRESS");

console.log(result.fairscore);       // 38.7
console.log(result.tier);            // "silver"
console.log(result.features.native_sol_percentile); // 96.73
console.log(result.badges.map(b => b.label));  // ["LST Staker", "SOL Maxi", ...]

// With social linking
const enriched = await client.human.getScore("WALLET_ADDRESS", {
  twitter: "handle",
});

Response shape (abridged — see Score Endpoint for the full schema):

{
  wallet: string;
  fairscore: number;            // 0–100 blended
  fairscore_base: number;       // on-chain only
  social_score: number;         // 0 if no X handle linked
  peer_score: number;           // 0 if no vouches received
  verified_human: boolean;      // VeryAI ZK palm-scan attestation
  tier: "bronze"|"silver"|"gold"|"platinum"|"diamond";
  badges: Badge[];
  actions: Action[];
  cached?: boolean;             // present on cache-hit responses
  timestamp: string;
  features: OnchainFeatures;    // 15 fields — see below
}

The features object contains portfolio composition (SOL, majors, stables, LSTs), capital flow, holding conviction, activity tempo, trading-behaviour (bot-likelihood) signals, and breadth metrics. Full field-level reference: Score Endpoint → Features.

human.computeScore(wallet, options?)

Force fresh recomputation, bypassing cache. Same shape as getScore. Use sparingly — charged as a new scoring call.

const fresh = await client.human.computeScore("WALLET", { twitter: "handle" });

Single-number shortcuts

When you only need a number, these avoid the full payload:

const { fair_score }   = await client.human.fairScoreOnly("WALLET");   // 0–1000 integer, blended
const { wallet_score } = await client.human.walletScoreOnly("WALLET"); // 0–1000 integer, on-chain only
const { social_score } = await client.human.socialScoreOnly("WALLET"); // 0–1000 integer, social only

These multiply the 0–100 decimal score by 10 and round to an integer.

Client-Side Insights

The client.insights.* namespace reproduces the dashboard's pillar and humanity-index derivations so you don't have to reimplement them. These helpers run locally — no network call — from a getScore result.

insights.pillars(score)

Returns the five dashboard pillars: Economy, Risk, Activity, Diversification, Social. Each resolves to "High" | "Medium" | "Low".

const score = await client.human.getScore("WALLET");
const pillars = client.insights.pillars(score);

// {
//   economy:         "High",
//   risk:            "Medium",
//   activity:        "High",
//   diversification: "Medium",
//   social:          "Low",
// }

Pillar → feature mapping:

PillarQuestionDriven by
EconomyCan they put capital behind their actions?major_, stable_, native_sol_, lst_percentile_score
RiskWill they stick around or dump?median_hold_days, conviction_ratio, no_instant_dumps
ActivityReal participant or ghost?tx_count, active_days, median_gap_hours
DiversificationExplorer or one-trick pony?platform_diversity, wallet_age_score
SocialDoes anyone know them?social_score, peer_score, linked X handle

insights.humanityIndex(score)

Returns a 0–100 Humanity Index plus a qualitative tier.

const humanity = client.insights.humanityIndex(score);

// {
//   score: 87,                          // 0–100
//   tier:  "likely_human",              // verified_human | likely_human | unverified
// }
  • verified_humanscore.verified_human === true. VeryAI has attested a ZK palm-scan proof.
  • likely_human — weighted function of tempo_cv, burst_ratio, conviction_ratio, no_instant_dumps, and social signals.
  • unverified — insufficient signal or bot-like patterns.

insights.fingerprint(score)

Groups the 15 raw features into the five human-readable categories used on the dashboard — Portfolio Composition, Capital Flow, Holding Conviction, Activity Tempo, Trading Behaviour.

const fp = client.insights.fingerprint(score);

fp.portfolio;          // { sol, majors, stables, lsts } — all 0–100 percentiles
fp.capital_flow;       // { net_sol_30d }
fp.holding_conviction; // { median_hold_days, conviction_ratio, no_instant_dumps }
fp.activity_tempo;     // { tx_count, active_days, median_gap_hours }
fp.trading_behaviour;  // { tempo_cv, burst_ratio }

Useful for rendering a dashboard-style insights card without duplicating the grouping logic.

Full Profile (convenience)

profile(wallet)

Fan-out helper that returns everything needed to render a complete wallet card in a single call. Parallelises human.getScore, pillar derivation, and humanity index.

const profile = await client.profile("WALLET");

profile.score;           // HumanScoreResponse
profile.pillars;         // PillarScores (Economy/Risk/Activity/Diversification/Social)
profile.humanity_index;  // { score, tier }
profile.fingerprint;     // Grouped feature categories

Error Handling

All methods throw on non-2xx responses. The error object includes status and code.

try {
  const score = await client.score("BAD_ADDRESS");
} catch (err) {
  switch (err.status) {
    case 400: console.error("Bad request:", err.code);   break; // missing_wallet, invalid_wallet, etc.
    case 402: console.error("Payment required");         break; // no fairkey + no x402 payment
    case 429: console.error("Rate limited");             break;
    case 502: console.error("Upstream unavailable");     break;
  }
}

Error codes:

StatusCodeMeaning
400missing_walletNo wallet address provided
400invalid_walletAddress not valid base58 (32–44 chars)
400invalid_presetUnknown preset name
400weights_must_sum_to_1Custom weights do not sum to 1.0 (±0.02)
400missing_weightsPOST to /v1/score/ai with no weights body
400too_many_walletsBatch > 25 wallets
402No fairkey and no x402 payment
429daily_limit_exceededPartner key daily limit reached
502upstream_errorScoring engine unreachable

x402 Pay-Per-Request (no API key needed)

For autonomous agents that prefer pay-as-you-go over subscriptions:

import { wrapFetch } from "@dexterai/x402/client";

const x402Fetch = wrapFetch(fetch, {
  walletPrivateKey: process.env.SOLANA_PRIVATE_KEY,
});

const res = await x402Fetch(
  "https://agent-api.fairscale.xyz/v1/score?wallet=WALLET_ADDRESS"
);
const data = await res.json();

Cost: $0.005 USDC per request (trust/agent endpoints), $0.50 USDC per credit assessment.

Decision Guide

GoalMethod
Check if an agent is trustworthyclient.score(wallet)
Gate access allow/denyclient.trustGate(wallet)
Score for a DeFi contextclient.scoreAI(wallet, { preset: "defi" })
Score for hiring / marketplaceclient.scoreAI(wallet, { preset: "hiring" })
Score with fully custom criteriaclient.scoreAI(wallet, { weights: {...} })
Screen multiple agents at onceclient.scoreBatch(wallets)
Full agent profile + signalsclient.agent(wallet)
Track score changes over timeclient.scoreHistory(wallet)
Browse verified agentsclient.directory({ verifiedOnly: true })
Top agents by metricclient.leaderboard({ metric: "work_history" })
Full credit assessment for lendingclient.credit(wallet, { amount: 5000 })
Full human wallet analysis (features, badges, tier)client.human.getScore(wallet)
Quick human wallet score (0–1000)client.human.fairScoreOnly(wallet)
On-chain-only wallet scoreclient.human.walletScoreOnly(wallet)
Derive Economy/Risk/Activity pillarsclient.insights.pillars(score)
Humanity Index (bot-likelihood)client.insights.humanityIndex(score)
Everything in one callclient.profile(wallet)