> ## Documentation Index
> Fetch the complete documentation index at: https://docs.webacy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ThreatClient

> Reference for ThreatClient methods covering address risk, sanctions screening, contract analysis, URL safety, vault scoring, and transaction simulation.

The `ThreatClient` provides access to Webacy's threat and risk analysis APIs. Use it to analyze addresses for security risks, screen for sanctions, check smart contract vulnerabilities, verify URL safety, assess ERC-4626 vault risk, and monitor stablecoin/RWA depeg risk.

## Initialization

```typescript theme={null}
import { ThreatClient, Chain } from '@webacy-xyz/sdk';

const client = new ThreatClient({
  apiKey: process.env.WEBACY_API_KEY,
  defaultChain: Chain.ETH, // Optional: set default chain
});
```

## Resources

The ThreatClient provides access to these resources:

| Resource       | Description                                                                     |
| -------------- | ------------------------------------------------------------------------------- |
| `addresses`    | Address risk analysis, sanctions screening, poisoning detection, quick profiles |
| `contracts`    | Smart contract security analysis and code analysis                              |
| `url`          | URL safety and phishing detection                                               |
| `wallets`      | Wallet activity and approval analysis                                           |
| `ledger`       | Hardware wallet transaction scanning                                            |
| `accountTrace` | Fund flow tracing                                                               |
| `transactions` | Transaction risk analysis                                                       |
| `scan`         | Transaction and EIP-712 message scanning                                        |
| `batch`        | Batch analysis for addresses, contracts, and transactions                       |
| `vaults`       | ERC-4626 vault risk scoring and due diligence                                   |
| `rwa`          | Stablecoin and RWA depeg risk monitoring                                        |
| `usage`        | API usage statistics                                                            |

***

## Addresses

### Analyze Address Risk

Get comprehensive risk analysis for any blockchain address.

```typescript theme={null}
const result = await client.addresses.analyze(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

console.log(result.overallRisk);  // 0-100 risk score
console.log(result.issues);       // Array of risk factors
console.log(result.isContract);   // true if smart contract
```

**Response:**

```json theme={null}
{
  "count": 1,
  "medium": 0,
  "high": 1,
  "overallRisk": 75.5,
  "issues": [
    {
      "tag": "Mixer User",
      "severity": "high",
      "description": "Address has interacted with mixing services"
    }
  ],
  "isContract": false
}
```

**Options:**

| Option         | Type           | Description                                          |
| -------------- | -------------- | ---------------------------------------------------- |
| `chain`        | `Chain`        | Blockchain to analyze (optional if defaultChain set) |
| `modules`      | `RiskModule[]` | Specific risk modules to run                         |
| `detailed`     | `boolean`      | Include detailed analysis data                       |
| `deployerRisk` | `boolean`      | Include deployer risk for contracts                  |

### Check Sanctions

Screen an address against OFAC and other sanctions lists.

```typescript theme={null}
const result = await client.addresses.checkSanctioned(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

if (result.is_sanctioned) {
  console.error('Address is sanctioned!');
  console.log(result.sanction_details);
}
```

### Check Address Poisoning

Detect address poisoning (dust attack) attempts.

```typescript theme={null}
const result = await client.addresses.checkPoisoning(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

if (result.is_poisoned) {
  console.warn('Address poisoning detected!');
  console.log(result.poisoning_details?.similar_addresses);
}
```

### Get Quick Profile

Get a lightweight risk profile with optional token approvals.

```typescript theme={null}
const result = await client.addresses.getQuickProfile(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  {
    chain: Chain.ETH,
    withApprovals: true,  // Include token approvals
  }
);

console.log(`Risk score: ${result.riskScore}`);
console.log(`Risk level: ${result.riskLevel}`);
console.log(`Account age: ${result.accountAge} days`);

// Check approvals if requested
for (const approval of result.approvals ?? []) {
  console.log(`${approval.symbol} approved to ${approval.spenderName}`);
}
```

**Options:**

| Option           | Type      | Description                                                |
| ---------------- | --------- | ---------------------------------------------------------- |
| `chain`          | `Chain`   | Blockchain to analyze (ETH, BASE, BSC, POL, OPT, ARB, SOL) |
| `withApprovals`  | `boolean` | Include token approval data                                |
| `hideTrustFlags` | `boolean` | Hide trust flags in response                               |

***

## Contracts

### Analyze Contract

Get security analysis for a smart contract.

```typescript theme={null}
const result = await client.contracts.analyze(
  '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT
  { chain: Chain.ETH }
);

console.log(result.overallRisk);
console.log(result.vulnerabilities);
```

### Get Contract Tax

Check buy/sell tax for a token contract.

```typescript theme={null}
const result = await client.contracts.getTax(
  '0xTokenAddress...',
  { chain: Chain.ETH }
);

console.log(`Buy tax: ${result.buyTax}%`);
console.log(`Sell tax: ${result.sellTax}%`);
```

### Get Code Analysis

Perform static code analysis on a contract's source code.

```typescript theme={null}
const result = await client.contracts.getCodeAnalysis(
  '0xContractAddress...',
  {
    chain: Chain.ETH,
    refreshCache: false,  // Use cached results if available
  }
);

console.log(`Total findings: ${result.findings.length}`);

for (const finding of result.findings) {
  console.log(`[${finding.severity}] ${finding.title}`);
  console.log(`  ${finding.description}`);
  console.log(`  Location: ${finding.location}`);
}
```

**Response:**

```json theme={null}
{
  "contractAddress": "0x...",
  "chain": "eth",
  "findings": [
    {
      "title": "Reentrancy vulnerability",
      "description": "External call before state update",
      "severity": "high",
      "location": "withdraw() line 45",
      "recommendation": "Use checks-effects-interactions pattern"
    }
  ],
  "analyzedAt": "2024-01-20T12:00:00Z"
}
```

***

## URL Safety

### Check URL

Analyze a URL for phishing and malware.

```typescript theme={null}
const result = await client.url.check('https://suspicious-site.com');

if (result.isPhishing) {
  console.error('Phishing site detected!');
}

console.log(result.riskScore);
console.log(result.categories);
```

***

## Wallets

### Get Approvals

List token approvals for a wallet.

```typescript theme={null}
const result = await client.wallets.getApprovals(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

for (const approval of result.approvals) {
  console.log(`${approval.token} approved to ${approval.spender}`);
  console.log(`Amount: ${approval.amount}`);
}
```

### Get Transactions

Get risk-scored transaction history for a wallet.

```typescript theme={null}
const result = await client.wallets.getTransactions(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

console.log(`Risk score: ${result.overallRisk}`);
console.log(`Issues found: ${result.count}`);

for (const issue of result.issues) {
  console.log(`[${issue.severity}] ${issue.tag}: ${issue.description}`);
}
```

**Response:**

```json theme={null}
{
  "count": 2,
  "overallRisk": 45,
  "issues": [
    {
      "tag": "Risky Interaction",
      "severity": "medium",
      "description": "Interacted with flagged address"
    }
  ]
}
```

***

## Account Trace

### Trace Fund Flows

Trace multi-hop fund flows for compliance and forensics.

```typescript theme={null}
const result = await client.accountTrace.trace(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

console.log(`Total connections: ${result.summary.totalConnections}`);
console.log(`High-risk: ${result.summary.highRiskConnections}`);

for (const conn of result.connections) {
  console.log(`${conn.address}: ${conn.relationship} - ${conn.riskFlags.join(', ')}`);
}
```

**Response:**

```json theme={null}
{
  "summary": {
    "totalConnections": 15,
    "highRiskConnections": 3
  },
  "connections": [
    {
      "address": "0xabc...",
      "relationship": "direct_transfer",
      "riskFlags": ["mixer_user", "high_risk"],
      "depth": 1
    }
  ]
}
```

***

## Usage

### Get API Usage

Monitor your API usage and quotas.

```typescript theme={null}
const usage = await client.usage.get();

console.log(`Requests used: ${usage.requestsUsed}`);
console.log(`Requests remaining: ${usage.requestsRemaining}`);
console.log(`Reset date: ${usage.resetDate}`);
```

### Get Max RPS

Get maximum requests per second for an organization over a time period.

```typescript theme={null}
const maxRps = await client.usage.getMaxRps({
  organization: 'my-org',
  from: Date.now() - 86400000, // 24 hours ago
  to: Date.now(),
});

console.log(`Max RPS: ${maxRps}`);
```

**Options:**

| Option         | Type     | Required | Description                                                                  |
| -------------- | -------- | -------- | ---------------------------------------------------------------------------- |
| `organization` | `string` | Yes      | Organization identifier                                                      |
| `from`         | `number` | Yes      | Start time as Unix timestamp in milliseconds (e.g., `Date.now() - 86400000`) |
| `to`           | `number` | Yes      | End time as Unix timestamp in milliseconds (e.g., `Date.now()`)              |

***

## Transactions

### Analyze Transaction

Get risk analysis for a blockchain transaction.

```typescript theme={null}
const result = await client.transactions.analyze(
  '0xTransactionHash...',
  { chain: Chain.ETH }
);

console.log(`Risk score: ${result.riskScore}`);
console.log(`Risk level: ${result.riskLevel}`);

for (const tag of result.riskTags ?? []) {
  console.log(`Risk: ${tag.tag} - ${tag.description}`);
}
```

**Supported chains:** ETH, BASE, BSC, POL, OPT, ARB, SOL, STELLAR

**Options:**

| Option           | Type      | Description                  |
| ---------------- | --------- | ---------------------------- |
| `chain`          | `Chain`   | Blockchain to analyze        |
| `hideTrustFlags` | `boolean` | Hide trust flags in response |

***

## Scan

### Scan Transaction

Scan a raw transaction for risks before signing.

```typescript theme={null}
const result = await client.scan.scanTransaction(
  '0xSignerAddress...',
  {
    tx: {
      from: '0xSignerAddress...',
      raw: '0xRawTransactionData...',
    },
    chain: 1, // Chain ID (1 = Ethereum)
    domain: 'app.example.com',  // Optional: dApp domain
  }
);

console.log(`Risk level: ${result.riskLevel}`);  // low, medium, high
console.log(`Warnings: ${result.warnings.length}`);

// Check asset changes
for (const change of result.assetChanges ?? []) {
  console.log(`${change.type}: ${change.amount} ${change.symbol}`);
}
```

**Supported chain IDs:** 1 (ETH), 56 (BSC), 137 (POL), 10 (OPT), 42161 (ARB), 8453 (BASE)

### Scan EIP-712 Message

Scan an EIP-712 typed data message before signing.

```typescript theme={null}
const result = await client.scan.scanEip712(
  '0xSignerAddress...',
  {
    msg: {
      from: '0xSignerAddress...',
      data: {
        types: {
          EIP712Domain: [
            { name: 'name', type: 'string' },
            { name: 'version', type: 'string' },
            { name: 'chainId', type: 'uint256' },
          ],
          Permit: [
            { name: 'owner', type: 'address' },
            { name: 'spender', type: 'address' },
            { name: 'value', type: 'uint256' },
          ],
        },
        primaryType: 'Permit',
        domain: {
          name: 'MyToken',
          version: '1',
          chainId: 1,
        },
        message: {
          owner: '0x...',
          spender: '0x...',
          value: '1000000000000000000',
        },
      },
    },
    domain: 'app.example.com',
  }
);

console.log(`Risk level: ${result.riskLevel}`);
console.log(`Message type: ${result.messageType}`);
```

***

## Batch

You can analyze multiple addresses, contracts, or transactions in a single request using the batch methods.

<Info>
  **Prerequisites:** You need an initialized `ThreatClient` and a `Chain` import. See [Installation](/sdk/installation) if you haven't set up the SDK yet.
</Info>

### Batch Addresses

You can analyze multiple addresses for risk in one call.

```typescript theme={null}
const result = await client.batch.addresses({
  addresses: [
    '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
    '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
  ],
  chain: Chain.ETH,
});
```

### Batch Contracts

You can analyze multiple smart contracts for risk in one call.

```typescript theme={null}
const result = await client.batch.contracts({
  addresses: [
    '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
    '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  ],
  chain: Chain.ETH,
});
```

### Batch Transactions

You can analyze multiple transactions for risk in one call.

```typescript theme={null}
const result = await client.batch.transactions({
  transactions: [
    '0xabc123...',
    '0xdef456...',
  ],
  chain: Chain.ETH,
});
```

**Request parameters:**

| Parameter                    | Type       | Description                                        |
| ---------------------------- | ---------- | -------------------------------------------------- |
| `addresses` / `transactions` | `string[]` | List of addresses or transaction hashes to analyze |
| `chain`                      | `Chain`    | Target blockchain                                  |

### Advanced: Large Batches

When you have a large number of items to analyze, you can split them into chunks and handle partial failures gracefully.

```typescript theme={null}
import { ThreatClient, Chain } from '@webacy-xyz/sdk';

const client = new ThreatClient({ apiKey: process.env.WEBACY_API_KEY });

async function batchAnalyzeAddresses(addresses: string[], chain: Chain) {
  const CHUNK_SIZE = 50;
  const successes: Record<string, unknown>[] = [];
  const failures: { addresses: string[]; error: string }[] = [];

  // Split into chunks
  for (let i = 0; i < addresses.length; i += CHUNK_SIZE) {
    const chunk = addresses.slice(i, i + CHUNK_SIZE);

    try {
      const result = await client.batch.addresses({
        addresses: chunk,
        chain,
      });
      successes.push(result);
    } catch (error) {
      failures.push({
        addresses: chunk,
        error: error instanceof Error ? error.message : String(error),
      });
    }
  }

  console.log(`Completed: ${successes.length} chunks succeeded, ${failures.length} failed`);
  return { successes, failures };
}
```

***

## Vaults

### List Vaults

Get a paginated list of ERC-4626 vaults with risk scores and ecosystem aggregates.

```typescript theme={null}
const result = await client.vaults.list();

console.log(`Total vaults: ${result.pagination.total}`);
console.log(`Total TVL: $${result.aggregates.total_tvl_usd}`);

for (const vault of result.items) {
  console.log(`${vault.metadata.name} — score: ${vault.risk.score}, TVL: $${vault.metadata.tvl_usd}`);
}
```

**Filtering and sorting:**

```typescript theme={null}
// Filter by protocol, chain, and risk tier
const risky = await client.vaults.list({
  protocol: 'morpho',
  chain: Chain.ETH,
  tier: 'high',
  sort: 'score_desc',
});

// Filter by underlying asset and attention needed
const urgent = await client.vaults.list({
  underlying: 'USDC',
  attentionNeeded: true,
});

// Filter by risk flags
const looping = await client.vaults.list({
  riskFlags: 'vault-high-looping,vault-upgradeable',
  riskFlagsMode: 'any',
});
```

**Options:**

| Option            | Type      | Description                                                                                    |
| ----------------- | --------- | ---------------------------------------------------------------------------------------------- |
| `chain`           | `Chain`   | Filter by chain (`ETH`, `ARB`, `BASE`, `OPT`, `POL`, `BSC`)                                    |
| `tier`            | `string`  | Risk tier: `low`, `medium`, `high`, `critical`, `unknown`                                      |
| `protocol`        | `string`  | DeFi protocol: `morpho`, `aave`, `compound`, `euler`, `spark`, `fluid`, `beefy`, `yearn`       |
| `contractType`    | `string`  | Vault type: `erc4626_vault`, `strategy_vault`, `lending_wrapper`, `bridge_vault`               |
| `underlying`      | `string`  | Underlying asset symbol (e.g. `USDC`)                                                          |
| `underlyingRisk`  | `string`  | Underlying risk tier: `battle_tested`, `medium_risk`, `high_risk`, `crypto`, `unknown`         |
| `minTvl`          | `number`  | Minimum TVL in USD                                                                             |
| `minScore`        | `number`  | Minimum risk score (0-100)                                                                     |
| `maxScore`        | `number`  | Maximum risk score (0-100)                                                                     |
| `attentionNeeded` | `boolean` | Only vaults needing attention                                                                  |
| `riskFlags`       | `string`  | Comma-separated risk tag keys (e.g. `vault-high-looping,vault-upgradeable`)                    |
| `riskFlagsMode`   | `string`  | Combine flags with `any` (OR) or `all` (AND)                                                   |
| `q`               | `string`  | Search by name, symbol, or address                                                             |
| `sort`            | `string`  | Sort: `score_desc`, `score_asc`, `tvl_desc`, `tvl_asc`, `apy_desc`, `looping_desc`, `name_asc` |
| `page`            | `number`  | Page number (1-indexed, default 1)                                                             |
| `pageSize`        | `number`  | Items per page (default 50, max 500)                                                           |

### List Vaults with Cursor Pagination

For efficient sequential pagination, use cursor-based pagination.

```typescript theme={null}
// First page using offset pagination
const first = await client.vaults.list({ pageSize: 100 });

// Subsequent pages using cursor
const second = await client.vaults.listCursor({
  cursor: 'opaque-cursor-from-previous-response',
  limit: 100,
});

if (second.next_cursor) {
  const third = await client.vaults.listCursor({
    cursor: second.next_cursor,
    limit: 100,
  });
}
```

### Get Vault Detail

Get detailed risk data for a specific vault, including looping markets, composition, and protocol-specific data.

```typescript theme={null}
const detail = await client.vaults.get(
  '0x1234...abcd',
  { chain: Chain.ETH }
);

console.log(`Score: ${detail.risk.score}`);
console.log(`TVL: $${detail.metadata.tvl_usd}`);
console.log(`Protocol: ${detail.metadata.protocol}`);
console.log(`Listing verdict: ${detail.metadata.listing_verdict}`);

// Check risk issues
for (const issue of detail.risk.issues) {
  for (const tag of issue.tags) {
    console.log(`[${tag.severity}] ${tag.name}: ${tag.description}`);
  }
}

// Check Morpho-specific data
if (detail.morpho) {
  console.log(`Morpho liquidity: $${detail.morpho.liquidity_usd}`);
  console.log(`Bad debt: $${detail.morpho.bad_debt_usd}`);
}

// Check vault composition
for (const asset of detail.vault_composition) {
  console.log(`${asset.symbol}: ${asset.share_pct}%`);
}

// Check Webacy code analysis findings
console.log(`Code risk: ${detail.webacy.code_risk_score}`);
console.log(`Contract risk: ${detail.webacy.contract_risk_score}`);
```

**Options:**

| Option  | Type    | Required | Description        |
| ------- | ------- | -------- | ------------------ |
| `chain` | `Chain` | Yes      | Blockchain network |

### Get Vault TVL History

Get the daily total value locked (USD) time series for a vault. The response hoists the most recent passing point to a `latest` aggregate so you can render the current value without iterating the full series.

```typescript theme={null}
// Default 30-day window
const history = await client.vaults.getTvlHistory(
  '0x9d39a5de30e57443bff2a8307a4256c8797a3497',
  { chain: Chain.ETH }
);

if (history.latest) {
  console.log(`Current TVL: $${history.latest.tvl_usd}`);
  console.log(`Quality: ${history.latest.quality_flag}`); // 'ok' | 'unknown' under the default filter
}
console.log(`${history.count} daily samples from ${history.from} to ${history.to}`);
console.log(`Stale reason: ${history.stale_reason}`); // 'fresh' | 'pipeline_lag' | 'all_filtered' | 'no_samples_yet'
console.log(`Dropped by quality filter: ${history.filtered_count}`);
console.log(`Schema version: ${history.schema_version}`);

for (const point of history.series) {
  console.log(`${point.ts}: $${point.tvl_usd} (${point.quality_flag})`);
}

// 7-day window for a tighter chart
const week = await client.vaults.getTvlHistory(
  '0x9d39a5de30e57443bff2a8307a4256c8797a3497',
  { chain: Chain.ETH, range: '7d' }
);

// Bypass the default quality filter to receive the full raw series,
// including 'capped' / 'diverged' / 'spike' samples
const raw = await client.vaults.getTvlHistory(
  '0x9d39a5de30e57443bff2a8307a4256c8797a3497',
  { chain: Chain.ETH, includeFlagged: true }
);

for (const point of raw.series) {
  if (point.quality_flag !== 'ok' && point.quality_flag !== 'unknown') {
    console.log(`Flagged ${point.quality_flag} at ${point.ts}: $${point.tvl_usd}`);
  }
}
// raw.filtered_count is always 0 when includeFlagged is true
```

By default the chart endpoints drop samples flagged as `capped`, `diverged`, or `spike`, so a single bad pricing artifact never appears as a misleading peak or trough — `count` may be smaller than the requested window and `filtered_count` reports how many points were excluded. A visible chart kink that lines up with `filtered_count` is normal and does not indicate a missed cron tick. `stale_reason` disambiguates the four post-filter states (`fresh`, `pipeline_lag`, `all_filtered`, `no_samples_yet`); `stale: boolean` is preserved as a back-compat alias (`true` iff `stale_reason !== 'fresh'`). See [Quality filtering](/vault-risk-intelligence#quality-filtering) for the full `quality_flag` table and when to set `includeFlagged: true`.

Tracked vaults with no samples yet return `count: 0`, `latest: null`, and `stale_reason: 'no_samples_yet'`; vaults outside the verified-vaults catalog throw a `404`.

**Options:**

| Option           | Type                             | Required | Description                                                                                                                                          |
| ---------------- | -------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chain`          | `Chain`                          | Yes      | Blockchain network (`ETH`, `ARB`, `BASE`, `OPT`, `POL`, `BSC`)                                                                                       |
| `range`          | `'7d' \| '30d' \| '60d' \| '3m'` | No       | Window length. Defaults to `30d`.                                                                                                                    |
| `includeFlagged` | `boolean`                        | No       | Bypass the default `quality_flag` allowlist and receive the full raw series, including `capped` / `diverged` / `spike` samples. Defaults to `false`. |
| `timeout`        | `number`                         | No       | Request timeout in milliseconds                                                                                                                      |
| `signal`         | `AbortSignal`                    | No       | Abort signal                                                                                                                                         |

### Get Vault Share Price History

Get the daily share price (USD) time series for a vault, with per-point trailing 7-day APY and a smoother trailing 30-day APY on the `latest` aggregate.

```typescript theme={null}
const history = await client.vaults.getSharePriceHistory(
  '0x9d39a5de30e57443bff2a8307a4256c8797a3497',
  { chain: Chain.ETH }
);

if (history.latest) {
  console.log(`Current share price: $${history.latest.share_price_usd}`);
  console.log(`Trailing 7d APY:  ${history.latest.apy_trailing_7d}`);
  console.log(`Trailing 30d APY: ${history.latest.apy_trailing_30d}`);
  console.log(`Quality: ${history.latest.quality_flag}`); // 'ok' | 'unknown' under the default filter
}

console.log(`Stale reason: ${history.stale_reason}`);
console.log(`Dropped by quality filter: ${history.filtered_count}`);
console.log(`Schema version: ${history.schema_version}`);

// Per-point apy_trailing_7d is null for points whose 7-day look-back
// sample is missing (e.g. the leading points of a longer range)
for (const point of history.series) {
  if (point.apy_trailing_7d === null) continue;
  console.log(`${point.ts}: $${point.share_price_usd} (7d APY ${point.apy_trailing_7d}, ${point.quality_flag})`);
}

// 60-day window for the chart
const chart = await client.vaults.getSharePriceHistory(
  '0x9d39a5de30e57443bff2a8307a4256c8797a3497',
  { chain: Chain.ETH, range: '60d' }
);
```

Per-point `apy_trailing_7d` is computed as `(price[t] / price[t-7d])^(365/7) - 1` and is `null` when the 7-day look-back sample is missing or the absolute APY exceeds 100 (clamped to suppress single-day pricing artifacts). `latest.apy_trailing_30d` uses the same shape over a 30-day window and is only surfaced on the `latest` aggregate.

The same quality-filtering rules as `getTvlHistory` apply: samples flagged as `capped` / `diverged` / `spike` are dropped from the default response, `filtered_count` reports how many were excluded (the 7-day look-back samples used to compute `apy_trailing_7d` are exempt and do not count toward `filtered_count`), and `stale_reason` disambiguates the post-filter staleness states. See [Quality filtering](/vault-risk-intelligence#quality-filtering) for the full table and pass `includeFlagged: true` to receive the raw series for research or marker overlays. The 404 behaviour matches `getTvlHistory`.

**Options:**

| Option           | Type                             | Required | Description                                                                                                                                          |
| ---------------- | -------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chain`          | `Chain`                          | Yes      | Blockchain network (`ETH`, `ARB`, `BASE`, `OPT`, `POL`, `BSC`)                                                                                       |
| `range`          | `'7d' \| '30d' \| '60d' \| '3m'` | No       | Window length. Defaults to `30d`.                                                                                                                    |
| `includeFlagged` | `boolean`                        | No       | Bypass the default `quality_flag` allowlist and receive the full raw series, including `capped` / `diverged` / `spike` samples. Defaults to `false`. |
| `timeout`        | `number`                         | No       | Request timeout in milliseconds                                                                                                                      |
| `signal`         | `AbortSignal`                    | No       | Abort signal                                                                                                                                         |

***

## Depeg Monitor (RWA)

### List Pegged Tokens

Get a paginated list of stablecoins and RWAs with depeg risk scores and ecosystem aggregates.

```typescript theme={null}
const result = await client.rwa.list();

console.log(`Total tokens: ${result.pagination.total}`);
console.log(`Stability index: ${result.aggregates.stability_index}`);

for (const token of result.items) {
  console.log(`${token.symbol} — score: ${token.score}, tier: ${token.tier}, price: ${token.price}`);
}
```

**Filtering and sorting:**

```typescript theme={null}
// Filter by denomination and risk tier
const usdCritical = await client.rwa.list({
  denomination: 'USD',
  tier: 'critical',
  sort: 'score',
  order: 'desc',
});

// Filter by token type tags
const goldTokens = await client.rwa.list({
  tags: ['gold', 'rwa'],
  minMcap: 1_000_000,
});

// View collapsed/dead tokens (graveyard)
const graveyard = await client.rwa.list({ collapsedOnly: true });
```

**Options:**

| Option          | Type       | Description                                                                             |
| --------------- | ---------- | --------------------------------------------------------------------------------------- |
| `chain`         | `Chain`    | Filter by chain (`ETH`, `ARB`, `POL`, `OPT`, `BASE`, `BSC`, `LINEA`)                    |
| `tier`          | `string`   | Risk tier: `critical`, `warning`, `watch`, `ok`                                         |
| `tags`          | `string[]` | Token types (OR logic): `standard`, `yield`, `rwa`, `gold`, `bridged`, `vault`          |
| `denomination`  | `string`   | Denomination code (e.g. `USD`, `EUR`, `XAU`)                                            |
| `minScore`      | `number`   | Minimum depeg risk score (0-100)                                                        |
| `maxScore`      | `number`   | Maximum depeg risk score (0-100)                                                        |
| `minMcap`       | `number`   | Minimum market cap in USD                                                               |
| `liquidity`     | `string`   | Liquidity tier: `high`, `medium`, `low`, `very_low`                                     |
| `q`             | `string`   | Search by symbol, name, or address                                                      |
| `sort`          | `string`   | Sort field: `score`, `symbol`, `chain`, `tier`, `abs_dev_clean`, `market_cap_usd`, `ts` |
| `order`         | `string`   | Sort direction: `asc`, `desc`                                                           |
| `showAll`       | `boolean`  | Include excluded/problematic tokens                                                     |
| `collapsedOnly` | `boolean`  | Only collapsed/dead tokens (graveyard)                                                  |
| `page`          | `number`   | Page number (1-indexed, default 1)                                                      |
| `pageSize`      | `number`   | Items per page (default 50, max 500)                                                    |

### Get Token Detail

Get detailed depeg risk for a specific pegged token, including historical time series and depeg events.

```typescript theme={null}
// Default 24h history
const detail24h = await client.rwa.get('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');

// Specify chain and 7 days of history
const detail = await client.rwa.get(
  '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  { chain: Chain.ETH, hours: 168 }
);

console.log(`Score: ${detail.snapshot.score}`);
console.log(`Tier: ${detail.snapshot.tier}`);
console.log(`Price: ${detail.snapshot.price}`);
console.log(`Deviation: ${detail.snapshot.abs_dev_clean}`);

// Check history
console.log(`History points: ${detail.history.series.length}`);
for (const point of detail.history.series) {
  console.log(`${point.ts}: score=${point.score}, price=${point.price}`);
}

// Check depeg events
for (const event of detail.depegEvents) {
  console.log(`${event.detectedAt}: ${event.oldTier} → ${event.newTier} (score: ${event.riskScore})`);
}
```

**Options:**

| Option  | Type     | Required | Description                                                     |
| ------- | -------- | -------- | --------------------------------------------------------------- |
| `chain` | `Chain`  | No       | Blockchain network (auto-resolved if token exists on one chain) |
| `hours` | `number` | No       | Hours of history (default 24, max 168 = 7 days)                 |

***

## Full Example

```typescript theme={null}
import { ThreatClient, Chain, ValidationError, RateLimitError } from '@webacy-xyz/sdk';

const client = new ThreatClient({
  apiKey: process.env.WEBACY_API_KEY,
  defaultChain: Chain.ETH,
});

async function analyzeWallet(address: string) {
  try {
    // Get overall risk
    const risk = await client.addresses.analyze(address);

    if (risk.overallRisk > 70) {
      console.warn(`High risk wallet: ${risk.overallRisk}`);

      // Check sanctions
      const sanctions = await client.addresses.checkSanctioned(address);
      if (sanctions.is_sanctioned) {
        throw new Error('Sanctioned address - cannot proceed');
      }

      // Check for address poisoning
      const poisoning = await client.addresses.checkPoisoning(address);
      if (poisoning.is_poisoned) {
        console.warn('Address may be a poisoning attempt');
      }
    }

    return { safe: risk.overallRisk < 50, risk };

  } catch (error) {
    if (error instanceof ValidationError) {
      console.error('Invalid address:', error.message);
    } else if (error instanceof RateLimitError) {
      console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
    }
    throw error;
  }
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="TradingClient" icon="chart-line" href="/sdk/trading-client">
    Holder analysis and sniper detection
  </Card>

  <Card title="Vault Risk API" icon="vault" href="../api-reference/vaults">
    Full vault risk API reference
  </Card>

  <Card title="Depeg Monitor API" icon="chart-mixed" href="../api-reference/depeg-monitor">
    Full depeg monitoring API reference
  </Card>

  <Card title="Error Handling" icon="bug" href="/sdk/error-handling">
    Handle errors gracefully
  </Card>

  <Card title="Chains" icon="link-horizontal" href="/sdk/chains">
    Supported blockchain networks
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Full API documentation
  </Card>
</CardGroup>
