TypeScript SDK
The official TypeScript SDK — zero dependencies, works in Node 18+ and any modern runtime with native fetch.
Installation
npm install @sova-intel/sdk
# or
pnpm add @sova-intel/sdk
Setup
API key
import { SovaIntelClient } from "@sova-intel/sdk";
const client = new SovaIntelClient({
baseUrl: "https://api.sova-intel.com/api/v1",
auth: {
kind: "apikey",
apiKey: process.env.SOVA_API_KEY!,
},
});
X402 autonomous payment
import { SovaIntelClient } from "@sova-intel/sdk";
const client = new SovaIntelClient({
baseUrl: "https://api.sova-intel.com/api/v1",
auth: {
kind: "x402",
buildPayment: async (payTo, amountBaseUnits) => {
// build USDC transferChecked tx, return base64 payment header
// see Authentication page for full implementation
},
},
});
Examples
Get a wallet HUD (1cr)
const hud = await client.getWalletHud("7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU");
console.log(hud.behaviorCode); // "W"
console.log(hud.winRate); // 0.67
console.log(hud.trimmedMeanPnl); // 12.4
console.log(hud.dataQualityTier); // "GOLD"
console.log(hud.isBot); // false
The SDK handles cold wallet 202 fallback automatically — you always get back a WalletHud.
Full wallet profile (5cr)
const profile = await client.getWalletProfile("7xKXtg...");
console.log(profile.summary.realizedPnl); // 142.87
console.log(profile.behavior?.tradingStyle); // "swing"
console.log(profile.pnl?.allTime?.netPnlSol); // 152.17
// KOL identity — present when the wallet belongs to a known trader
if (profile.kol) {
console.log(profile.kol.name); // "Ansem"
console.log(profile.kol.twitter); // "https://x.com/blknoiz06"
}
Per-token PnL table (3cr)
const tokens = await client.getWalletTokens("7xKXtg...", {
pageSize: 50,
sortBy: "realizedPnlSol",
sortOrder: "DESC",
});
for (const token of tokens.data) {
console.log(token.tokenAddress, token.realizedPnlSol, token.roi);
}
Batch HUD for multiple wallets (5cr flat)
const batch = await client.batchHud(["addr1", "addr2", "addr3"]);
for (const [address, hud] of Object.entries(batch.huds)) {
console.log(address, hud.behaviorCode, hud.winRate);
}
// Wallets queued for analysis (missing/stale) — each has a jobId to poll
console.log("Queued:", batch.queued);
// Wallets skipped (invalid, over limit, etc.)
console.log("Skipped:", batch.skipped);
Holder profiles — async (20cr)
The poll variant queues the job, polls until complete, and returns the result:
import type { HolderProfilesResult } from "@sova-intel/sdk";
const result = await client.pollHolderProfiles<HolderProfilesResult>(
"So11111111111111111111111111111111111111112",
20, // top N holders
);
for (const holder of result.profiles) {
console.log(holder.rank, holder.walletAddress, holder.supplyPercent, holder.behaviorType);
}
Similarity analysis — async (20cr)
import type { SimilarityResult } from "@sova-intel/sdk";
const result = await client.pollSimilarity<SimilarityResult>(["addr1", "addr2", "addr3"]);
console.log(result.globalMetrics.averageSimilarity); // 0.73
for (const pair of result.pairwiseSimilarities) {
console.log(pair.walletA, pair.walletB, pair.binaryScore, pair.capitalScore);
}
Bundled deep analysis — async (35cr)
Holder profiles + similarity in one call. The server discovers holder addresses itself — no need to supply them upfront. Results are returned sequentially: holder-profiles first, then similarity (chained automatically by the processor).
import type { HolderProfilesResult, SimilarityResult } from "@sova-intel/sdk";
const { holderProfiles, similarity } = await client.pollDeepAnalysis<
HolderProfilesResult,
SimilarityResult
>("So11111111111111111111111111111111111111112", 20);
for (const holder of holderProfiles.profiles) {
console.log(holder.rank, holder.walletAddress, holder.behaviorType);
}
console.log(similarity.globalMetrics.averageSimilarity);
If you want the job descriptors without blocking, use queueDeepAnalysis:
const jobs = await client.queueDeepAnalysis("TOKEN_MINT", 20);
// jobs.holderProfiles.jobId — poll this first
// jobs.similarity.resultKey — poll this after holderProfiles completes
console.log(jobs.holderProfiles.monitoringUrl);
console.log(jobs.similarity.resultKey);
Agent-optimised holder profiles (20cr)
Returns the same behavioral data as pollHolderProfiles but in a compact, agent-friendly shape: a population-level aggregate block first, then slim per-holder profiles (~1–2k tokens vs ~10k+ for the full shape).
import type { AgentHolderProfilesResult } from "@sova-intel/sdk";
const result = await client.pollTokenHoldersAgent(
"So11111111111111111111111111111111111111112",
20,
);
// Population-level signal — make a buy/skip decision without scanning profiles
console.log(result.aggregate.top5SupplyPct); // supply % by top 5 holders
console.log(result.aggregate.avgWalletPnlSol); // average holder PnL
console.log(result.aggregate.behaviorDistribution);
// [{ behaviorType: "SWING_TRADER", count: 8, supplyPct: 31.2 }, ...]
// Per-holder profiles — currentHoldings[] replaced with holdingsSummary
for (const holder of result.profiles) {
console.log(holder.rank, holder.behaviorType, holder.holdingsSummary.totalPositions);
}
Use the queue variant if you need the job descriptor:
const job = await client.queueTokenHoldersAgent("TOKEN_MINT", 20);
// job.agentResultKey — fetch via GET /jobs/result/by-key?key={agentResultKey}
// job.resultKey — full developer result still available here
Agent-optimised similarity (20cr)
Returns a compact similarity result with a single coordinationScore (0–1), filtered meaningful pairs, and coordination flags. Debug fields and low-signal pairs are dropped.
import type { AgentSimilarityResult } from "@sova-intel/sdk";
const result = await client.pollWalletSimilarityAgent(["addr1", "addr2", "addr3"]);
// Single number for quick agent decisions
console.log(result.coordinationScore); // 0.82 — high coordination signal
// Only pairs that cleared the signal filter (score >= 0.15 OR >=20 shared tokens)
for (const pair of result.pairs) {
console.log(pair.walletA, pair.walletB, pair.similarityScore);
if (pair.flag) {
console.log("Flag:", pair.flag);
// "HIGH_SIMILARITY" | "HIGH_OVERLAP" | "HIGH_SIMILARITY_AND_OVERLAP"
}
}
console.log(result.metadata.flaggedPairs); // pairs with coordination signal
console.log(result.metadata.meaningfulPairs); // total pairs with signal
Client Configuration
const client = new SovaIntelClient({
baseUrl: "https://api.sova-intel.com/api/v1", // required
auth: { ... }, // required
pollIntervalMs: 5000, // default: 5000ms
maxPollAttempts: 60, // default: 60 (~5 min)
});
Error Handling
import { SovaIntelClient, SovaHttpError, X402PaymentError } from "@sova-intel/sdk";
try {
const hud = await client.getWalletHud(address);
} catch (err) {
if (err instanceof X402PaymentError) {
// Payment failed
console.error("Payment error:", err.body);
} else if (err instanceof SovaHttpError) {
switch (err.status) {
case 404: console.error("Wallet not found or result expired"); break;
case 422: console.error("System/program wallet — skip"); break;
case 500: console.error("Server error — retry with backoff"); break;
}
}
}
Exported Types
import type {
WalletHud,
WalletProfileResponse,
WalletSummary,
WalletBehavior,
KolIdentity,
PnlAllTime,
DataQualityTier,
TokenPnlRow,
TokenPnlResponse,
TokenPnlParams,
BatchHudResponse,
BatchHudQueuedEntry,
HolderProfile,
HolderProfilesResult,
SimilarityResult,
SimilarityPairResult,
SimilarityGlobalMetrics,
// Agent-optimised results
AgentHolderProfilesResult,
AgentHolderAggregate,
AgentHolderProfile,
AgentHoldingsSummary,
AgentSimilarityResult,
AgentSimilarityPair,
// Job accepted responses (agent variants)
HolderProfilesAgentJobAcceptedResponse,
SimilarityAgentJobAcceptedResponse,
// Async jobs
JobAcceptedResponse,
DeepJobAcceptedResponse,
JobStatus,
SovaIntelClientConfig,
Auth,
ApiKeyAuth,
X402Auth,
} from "@sova-intel/sdk";
Method Reference
| Method | Endpoint | Credits |
|---|---|---|
getWalletProfile(addr) | GET /intel/wallet/:addr | 5 |
getWalletHud(addr) | GET /intel/wallet/:addr/hud | 1 |
getWalletTokens(addr, params?) | GET /intel/wallet/:addr/tokens | 3 |
batchHud(wallets[]) | POST /intel/wallets/batch-hud | 5 |
queueHolderProfiles(mint, topN?) | POST /intel/token/:mint/holders | 20 |
pollHolderProfiles(mint, topN?) | queue + auto-poll helper | no extra charge |
queueTokenHoldersAgent(mint, topN?) | POST /intel/token/:mint/holders/agent | 20 |
pollTokenHoldersAgent(mint, topN?) | queue + auto-poll helper | no extra charge |
queueSimilarity(wallets[]) | POST /intel/wallets/similarity | 20 |
pollSimilarity(wallets[]) | queue + auto-poll helper | no extra charge |
queueWalletSimilarityAgent(wallets[]) | POST /intel/wallets/similarity/agent | 20 |
pollWalletSimilarityAgent(wallets[]) | queue + auto-poll helper | no extra charge |
queueDeepAnalysis(mint, topN?) | POST /intel/token/:mint/holders/deep | 35 |
pollDeepAnalysis(mint, topN?) | queue + auto-poll helper | no extra charge |