One query. Three protocols. Three risk questions.
Messari's common schema gives Aave v3, Compound v3 and Spark Lend the same entities — Account, Position, Market, Token, FinancialsDailySnapshot. So the query below is written once and sent unmodified to all three. Adding a fourth protocol is one row in LENDING_SUBGRAPHS.
Whose exposure?
This account is fresh, so it has no borrows anywhere — the honest answer is $0. Point the same query at a real mainnet borrower and the exposure cap trips: the policy restricts new borrowing instead of liquidating, because debt owed elsewhere is not a breach of this position's terms.
Same document, every protocol
| Deployment | Schema | This account | Protocol borrows | Liquidated 7d | ETH markets | ETH price |
|---|
Written once
query GalvanicProtocolRisk($account: ID!) {
account(id: $account) {
positions(where: { side: BORROWER, hashClosed: null }, first: 1000) {
balance
asset { symbol decimals lastPriceUSD }
}
}
financialsDailySnapshots(first: 7, orderBy: timestamp, orderDirection: desc) {
dailyLiquidateUSD
totalBorrowBalanceUSD
}
markets(first: 200, where: { isActive: true }) {
totalBorrowBalanceUSD
totalDepositBalanceUSD
inputToken { symbol lastPriceUSD }
}
}Not one field here is protocol-specific. USD values for positions are derived the standard Messari way — balance / 10^decimals × asset.lastPriceUSD — which works identically everywhere precisely because Token.lastPriceUSD is part of the shared schema.