# Scallop Query Data

> Query Scallop protocol data - market pools, balances, obligations, prices, and portfolio info. Use when user says "query", "get market data", "check balance", "get obligation", "market APY", "pool data", "utilization rate", "portfolio", "supply APY", "borrow APY", or asks about reading on-chain Scallop data without modifying state.

- Skill: `scallop-io/scallop-query-data` (Agent Skill)
- Install (CLI): `npx skillmds@latest add scallop-io/scallop-query-data`
- Raw SKILL.md: https://api.skillmd.com/api/skills/scallop-io/scallop-query-data/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: scallop-io (https://skillmd.com/u/scallop-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/scallop-io/scallop-query-data

---


# Query Protocol Data

Read on-chain Scallop protocol data: market pools, balances, obligations, prices, and user portfolios.

## Overview

`ScallopQuery` provides read-only access to all protocol data. No transaction signing required — just an RPC connection.

```python
from sui_scallop_sdk import ScallopClient

client = ScallopClient(network="mainnet")
query = client.create_query()
```

Or with a wallet address for user-specific queries:

```python
client = ScallopClient(
    network="mainnet",
    wallet_address="0xYOUR_ADDRESS"
)
query = client.create_query()
```

## ScallopQuery Methods

| Method | Returns | Purpose |
|--------|---------|---------|
| `get_market_data(coin_name?)` | `dict[str, MarketPool]` | Market pool stats (APY, utilization, etc.) |
| `get_balance(owner, coin_type?)` | `int` | Token balance for address |
| `get_coins(owner, coin_type?)` | `list[dict]` | All coin objects owned by address |
| `get_coin_price(coin_name)` | `Decimal \| None` | Current USD price via Pyth oracle |
| `get_obligation(obligation_id)` | `ObligationInfo` | Obligation with parsed data |
| `get_obligation_with_prices(obligation_id)` | `ObligationInfo` | Obligation with fresh USD values |
| `get_obligation_account(obligation_id)` | `ObligationAccount \| None` | Raw obligation account data |
| `list_user_obligations(address?)` | `list[str]` | All obligation IDs for a wallet |
| `get_object(object_id)` | `dict` | Generic on-chain object query |

## Market Data

Query lending pool statistics:

```python
# Get all markets
markets = query.get_market_data()
for coin_name, pool in markets.items():
    print(f"{coin_name.upper()}:")
    print(f"  Supply APY: {pool.supply_apy:.2f}%")
    print(f"  Borrow APY: {pool.borrow_apy:.2f}%")
    print(f"  Utilization: {pool.utilization_rate:.2%}")
    print(f"  Collateral Factor: {pool.collateral_factor:.2f}")

# Get specific market
sui_markets = query.get_market_data("sui")
sui_pool = sui_markets["sui"]
print(f"SUI Supply Amount: {sui_pool.supply_amount}")
print(f"SUI Borrow Amount: {sui_pool.borrow_amount}")
```

### MarketPool Fields

```python
from sui_scallop_sdk import MarketPool

# MarketPool is a Pydantic model with these fields:
# coin_name: str            - SDK coin name (e.g., "sui")
# coin_type: str            - Full coin type
# supply_amount: Decimal    - Total supplied
# borrow_amount: Decimal    - Total borrowed
# supply_apy: Decimal       - Supply APY percentage
# borrow_apy: Decimal       - Borrow APY percentage
# utilization_rate: Decimal  - Pool utilization (0-1)
# collateral_factor: Decimal - Collateral factor (0-1)
# borrow_factor: Decimal    - Borrow weight factor
# reserve_factor: Decimal   - Reserve factor (0-1)
# price_usd: Decimal        - Current USD price
```

## Balance Queries

```python
# Get SUI balance (returns raw amount in base units)
from sui_scallop_sdk.constants import SDK_NAME_TO_COIN_TYPE

sui_type = SDK_NAME_TO_COIN_TYPE["sui"]
balance = query.get_balance(wallet_address, sui_type)
print(f"SUI Balance: {balance / 1e9:.4f} SUI")

# Get all coin objects (useful for manual coin selection)
coins = query.get_coins(wallet_address, sui_type)
for coin in coins:
    print(f"  Coin ID: {coin['coinObjectId']}, Amount: {coin['balance']}")
```

Also available directly on `ScallopClient`:

```python
balance = client.get_balance(coin_type=sui_type)
```

## Obligation Queries

### List User Obligations

```python
# List all obligation IDs for a wallet
obligation_ids = query.list_user_obligations(wallet_address)
print(f"Found {len(obligation_ids)} obligations")
for oid in obligation_ids:
    print(f"  - {oid}")
```

### Get Obligation Details

```python
# Basic obligation data (no USD values)
obligation = query.get_obligation(obligation_id)

print(f"Debts: {len(obligation.debts)}")
for debt in obligation.debts:
    print(f"  {debt.coin_name}: {debt.amount_coin} ({debt.coin_symbol})")

print(f"Collaterals: {len(obligation.collaterals)}")
for col in obligation.collaterals:
    print(f"  {col.coin_name}: {col.amount_coin} ({col.coin_symbol})")
```

### Get Obligation with USD Values

```python
# Fetches fresh oracle prices and calculates USD values
obligation = query.get_obligation_with_prices(obligation_id)

print(f"Total Debt: ${obligation.total_debt_usd:.2f}")
print(f"Total Collateral: ${obligation.total_collateral_usd:.2f}")
print(f"Risk Level: {obligation.risk_level:.4f}")
print(f"Liquidatable: {obligation.is_liquidatable}")
print(f"Bad Debt: {obligation.is_bad_debt}")

# Per-asset USD values
for debt in obligation.debts:
    print(f"  {debt.coin_symbol}: ${debt.value_usd:.2f}")
```

### ObligationAccount vs ObligationInfo

| Model | Key Difference | Use Case |
|-------|---------------|----------|
| `ObligationAccount` | Debts/collaterals as `dict[str, T \| None]` | Raw data, keyed by coin name |
| `ObligationInfo` | Debts/collaterals as `list[T]` (non-null only) | Clean display, computed properties |

```python
# ObligationAccount - raw, keyed data
account = query.get_obligation_account(obligation_id)
if account:
    usdc_debt = account.debts.get("usdc")  # DebtInfo | None

    # Convert to ObligationInfo
    info = account.to_obligation_info()
```

## Data Models

### DebtInfo

```python
# Fields:
# coin_type: str          - Full coin type
# coin_name: str          - SDK name (e.g., "usdc")
# coin_symbol: str        - Display symbol (e.g., "wUSDC")
# coin_display_name: str  - Full name (e.g., "Wormhole USDC")
# amount: int             - Raw amount with decimals
# amount_coin: Decimal    - Human-readable amount
# value_usd: Decimal      - USD value (populated by get_obligation_with_prices)
```

### CollateralInfo

Same fields as `DebtInfo` — represents a collateral position.

### ObligationInfo Computed Properties

```python
obligation.is_liquidatable  # bool: risk_level >= 1.0
obligation.total_debt_usd   # Decimal: sum of all debt USD values
obligation.total_collateral_usd  # Decimal: sum of all collateral USD values
obligation.is_bad_debt      # bool: has debt but no collateral
```

## Price Queries

```python
from decimal import Decimal

price = query.get_coin_price("sui")
if price:
    print(f"SUI: ${price:.4f}")  # Decimal precision

# Query multiple prices
for coin in ["sui", "usdc", "eth", "btc"]:
    p = query.get_coin_price(coin)
    if p:
        print(f"{coin.upper()}: ${p:.4f}")
```

For more advanced price operations, see the [oracle skill](../scallop-oracle/SKILL.md).

## Generic Object Query

Query any on-chain object by ID:

```python
obj = query.get_object(
    "0x1234...",
    show_content=True,
    show_type=True,
)
print(obj)  # Raw dict from Sui RPC
```

## Complete Example: Portfolio Dashboard

```python
from sui_scallop_sdk import ScallopClient

client = ScallopClient(
    secret_key="...",
    network="mainnet",
)
query = client.create_query()

# 1. Get all obligations
obligations = query.list_user_obligations(client.wallet_address)
print(f"=== Portfolio: {len(obligations)} obligations ===\n")

total_debt = 0
total_collateral = 0

for oid in obligations:
    ob = query.get_obligation_with_prices(oid)

    print(f"Obligation: {oid[:16]}...")
    print(f"  Risk: {ob.risk_level:.4f} {'⚠️ DANGER' if ob.risk_level > 0.8 else '✅'}")

    for debt in ob.debts:
        print(f"  Debt: {debt.amount_coin} {debt.coin_symbol} (${debt.value_usd:.2f})")
    for col in ob.collaterals:
        print(f"  Collateral: {col.amount_coin} {col.coin_symbol} (${col.value_usd:.2f})")

    total_debt += float(ob.total_debt_usd)
    total_collateral += float(ob.total_collateral_usd)
    print()

# 2. Get market rates
markets = query.get_market_data()
print("=== Market Rates ===")
for name, pool in markets.items():
    print(f"{name}: Supply {pool.supply_apy:.2f}% | Borrow {pool.borrow_apy:.2f}%")

print(f"\n=== Summary ===")
print(f"Total Debt: ${total_debt:,.2f}")
print(f"Total Collateral: ${total_collateral:,.2f}")
```

## Error Handling

```python
from sui_scallop_sdk.exceptions import ObligationNotFoundError, ScallopQueryError

try:
    ob = query.get_obligation("0xinvalid")
except ObligationNotFoundError as e:
    print(f"Obligation not found: {e.obligation_id}")
except ScallopQueryError as e:
    print(f"Query failed: {e}")
```

## Limits, Fees & Portfolio Queries (both SDKs)

These read-only queries are exposed as methods on `ScallopQuery` in `@scallop-io/sui-scallop-sdk` (verified against v4.3.0) **and** have Python equivalents in `sui-scallop-sdk` **>= 0.3.0a1** (`query.py`): `get_supply_limit(s)`, `get_borrow_limit(s)`, `get_isolated_assets`, `is_isolated_asset`, `get_flash_loan_fee(s)`, `get_user_portfolio`, `get_lendings`, `get_tvl`, `get_asset_oracles`, `get_price_update_policies`. The only genuinely TS-only query in this family is `getSwitchboardOnDemandAggregatorObjectIds`.

> **SDK note**: TS SDK v4.3.0 exports the package root plus the `./client`, `./query`, `./builder`, `./types`, `./errors`, and `./logger` subpaths. Internal deep paths are not exported — call these via `scallop.client.query.*` (or the `./query` subpath entry).

### Borrow / Supply Limits

Per-asset caps configured by the protocol (separate from per-obligation health).

```typescript
const scallopSDK = new Scallop({ networkType: 'mainnet' });
await scallopSDK.init();
const query = scallopSDK.client.query;

const borrowLimit = await query.getPoolBorrowLimit('usdc'); // Promise<string>
const supplyLimit = await query.getPoolSupplyLimit('usdc'); // Promise<string>
// Decimal strings in the asset's base units; never null — '0' when unset/unreadable.
```

Python: `query.get_supply_limit('usdc')` / `query.get_borrow_limit('usdc')` return `Decimal` in human-readable coin units.

### Flash-Loan Fee Rates

```typescript
const fees = await query.getFlashLoanFees(['usdc', 'sui']);
// Record<coinName, number> — pre-computed fee ratios, e.g. fees.usdc === 0.0005
```

Python: `query.get_flash_loan_fees(['usdc'])` → `dict[str, Decimal]`.

### Isolated Asset Checks

Some collaterals are flagged "isolated" — they can be the *only* collateral in their obligation. Liquidator/strategist code must respect this before composing positions.

```typescript
const isolated = await query.getIsolatedAssets(); // array of isolated coin names
const flag     = await query.isIsolatedAsset('musd'); // boolean
```

### Portfolio / TVL Aggregates

```typescript
const portfolio = await query.getUserPortfolio({ walletAddress: ownerAddress });
// portfolio.lendings   -> supplied positions across all assets
// portfolio.borrowings -> every obligation with collaterals/borrowedPools + USD values
// portfolio.veScas     -> array of veSCA positions

const lendings = await query.getLendings(undefined, ownerAddress);
const tvl      = await query.getTvl();
// tvl => { supplyValue, borrowValue, totalValue, supplyLendingValue, supplyCollateralValue, ... }
```

### Switchboard On-Demand Aggregators (TS-only)

```typescript
const aggIds = await query.getSwitchboardOnDemandAggregatorObjectIds(['sui', 'usdc']);
```

For a dedicated walkthrough and dashboard examples, see [portfolio-analytics](../scallop-portfolio-analytics/SKILL.md). For limit-aware borrowing/supplying logic, see [market-limits](../scallop-market-limits/SKILL.md).

## References

- [Supported Coins](../../references/supported-coins.md) - All supported assets with decimals
- [Market Coin Types](../../references/market-coin-types.md) - Market coin type mappings
- [Oracle Skill](../scallop-oracle/SKILL.md) - Advanced price queries
- [Market Limits Skill](../scallop-market-limits/SKILL.md) - Borrow/supply caps + isolated assets
- [Portfolio Analytics Skill](../scallop-portfolio-analytics/SKILL.md) - User portfolio + TVL

