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.
from sui_scallop_sdk import ScallopClient
client = ScallopClient(network="mainnet")
query = client.create_query()
Or with a wallet address for user-specific queries:
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:
# 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
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
# 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:
balance = client.get_balance(coin_type=sui_type)
Obligation Queries
List User Obligations
# 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
# 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
# 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 |
# 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
# 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
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
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.
Generic Object Query
Query any on-chain object by ID:
obj = query.get_object(
"0x1234...",
show_content=True,
show_type=True,
)
print(obj) # Raw dict from Sui RPC
Complete Example: Portfolio Dashboard
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
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./loggersubpaths. Internal deep paths are not exported — call these viascallop.client.query.*(or the./querysubpath entry).
Borrow / Supply Limits
Per-asset caps configured by the protocol (separate from per-obligation health).
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
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.
const isolated = await query.getIsolatedAssets(); // array of isolated coin names
const flag = await query.isIsolatedAsset('musd'); // boolean
Portfolio / TVL Aggregates
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)
const aggIds = await query.getSwitchboardOnDemandAggregatorObjectIds(['sui', 'usdc']);
For a dedicated walkthrough and dashboard examples, see portfolio-analytics. For limit-aware borrowing/supplying logic, see market-limits.
References
- Supported Coins - All supported assets with decimals
- Market Coin Types - Market coin type mappings
- Oracle Skill - Advanced price queries
- Market Limits Skill - Borrow/supply caps + isolated assets
- Portfolio Analytics Skill - User portfolio + TVL