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:
| Namespace | Host | Use for |
|---|---|---|
client.* (root) | agent-api.fairscale.xyz | Agents, trust scoring, credit, directory |
client.human.* | api.fairscale.xyz | Human 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:
| Preset | verification | wallet_history | work_history | network_quality | peer_reputation |
|---|---|---|---|---|---|
default | 0.30 | 0.25 | 0.10 | 0.25 | 0.10 |
trust_focused | 0.50 | 0.20 | 0.10 | 0.10 | 0.10 |
work_focused | 0.20 | 0.15 | 0.40 | 0.15 | 0.10 |
defi | 0.25 | 0.30 | 0.10 | 0.25 | 0.10 |
hiring | 0.35 | 0.15 | 0.25 | 0.15 | 0.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:
| Band | Score | Meaning |
|---|---|---|
prime | 75–100 | Eligible for unsecured credit |
near_prime | 60–74 | Moderate collateral recommended |
subprime | 45–59 | Full collateral, short terms |
deep_subprime | 25–44 | Over-collateralised only |
decline | 0–24 | Decline 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:
| Pillar | Question | Driven by |
|---|---|---|
| Economy | Can they put capital behind their actions? | major_, stable_, native_sol_, lst_percentile_score |
| Risk | Will they stick around or dump? | median_hold_days, conviction_ratio, no_instant_dumps |
| Activity | Real participant or ghost? | tx_count, active_days, median_gap_hours |
| Diversification | Explorer or one-trick pony? | platform_diversity, wallet_age_score |
| Social | Does 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_human—score.verified_human === true. VeryAI has attested a ZK palm-scan proof.likely_human— weighted function oftempo_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:
| Status | Code | Meaning |
|---|---|---|
| 400 | missing_wallet | No wallet address provided |
| 400 | invalid_wallet | Address not valid base58 (32–44 chars) |
| 400 | invalid_preset | Unknown preset name |
| 400 | weights_must_sum_to_1 | Custom weights do not sum to 1.0 (±0.02) |
| 400 | missing_weights | POST to /v1/score/ai with no weights body |
| 400 | too_many_wallets | Batch > 25 wallets |
| 402 | — | No fairkey and no x402 payment |
| 429 | daily_limit_exceeded | Partner key daily limit reached |
| 502 | upstream_error | Scoring 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
| Goal | Method |
|---|---|
| Check if an agent is trustworthy | client.score(wallet) |
| Gate access allow/deny | client.trustGate(wallet) |
| Score for a DeFi context | client.scoreAI(wallet, { preset: "defi" }) |
| Score for hiring / marketplace | client.scoreAI(wallet, { preset: "hiring" }) |
| Score with fully custom criteria | client.scoreAI(wallet, { weights: {...} }) |
| Screen multiple agents at once | client.scoreBatch(wallets) |
| Full agent profile + signals | client.agent(wallet) |
| Track score changes over time | client.scoreHistory(wallet) |
| Browse verified agents | client.directory({ verifiedOnly: true }) |
| Top agents by metric | client.leaderboard({ metric: "work_history" }) |
| Full credit assessment for lending | client.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 score | client.human.walletScoreOnly(wallet) |
| Derive Economy/Risk/Activity pillars | client.insights.pillars(score) |
| Humanity Index (bot-likelihood) | client.insights.humanityIndex(score) |
| Everything in one call | client.profile(wallet) |