Skip to main content

Multi-protocol portfolio snapshot

Fetch a wallet’s positions across all protocols in a single request. Each protocol returns its own typed response — use inline fragments to select the fields you need.
query {
  walletPositions(inputs: [
    { protocol: "morpho",   chainId: 1,     walletAddress: "0x..." }
    { protocol: "aave",     chainId: 1,     walletAddress: "0x..." }
    { protocol: "pendle",   chainId: 1,     walletAddress: "0x..." }
    { protocol: "fluid",    chainId: 1,     walletAddress: "0x..." }
    { protocol: "compound", chainId: 1,     walletAddress: "0x..." }
    { protocol: "neutrl",   chainId: 1,     walletAddress: "0x..." }
    { protocol: "avantis",  chainId: 8453,  walletAddress: "0x..." }
    { protocol: "avant",    chainId: 43114, walletAddress: "0x..." }
    { protocol: "midas",    chainId: 1,     walletAddress: "0x..." }
  ]) {
    data {
      ... on MorphoWalletPositions   { protocol chainId walletAddress }
      ... on AaveWalletPositions     { protocol chainId walletAddress }
      ... on PendleWalletPositions   { protocol chainId walletAddress }
      ... on FluidWalletPositions    { protocol chainId walletAddress }
      ... on CompoundWalletPositions { protocol chainId walletAddress }
      ... on NeutrlWalletPositions   { protocol chainId walletAddress }
      ... on AvantisWalletPositions  { protocol chainId walletAddress }
      ... on AvantWalletPositions    { protocol chainId walletAddress }
      ... on MidasWalletPositions    { protocol chainId walletAddress }
    }
    errors {
      protocol chainId walletAddress
      error { code message retryable }
    }
  }
}
Maximum 5 inputs per request. Split larger queries across multiple requests.

Vault yield comparison

Compare yields across vault-style protocols by querying positions with APY fields:
query {
  walletPositions(inputs: [
    { protocol: "morpho",  chainId: 1,     walletAddress: "0x..." }
    { protocol: "neutrl",  chainId: 1,     walletAddress: "0x..." }
    { protocol: "avantis", chainId: 8453,  walletAddress: "0x..." }
    { protocol: "avant",   chainId: 43114, walletAddress: "0x..." }
  ]) {
    data {
      ... on MorphoWalletPositions {
        protocol
        vaultV2Positions { vaultName assetsUsd apy }
      }
      ... on NeutrlWalletPositions {
        protocol
        vaultPosition { balanceUsd apy }
      }
      ... on AvantisWalletPositions {
        protocol
        vaultPosition { balanceUsd apy }
      }
      ... on AvantWalletPositions {
        protocol
        vaultPosition { balanceUsd apy }
      }
    }
    errors { protocol error { code message } }
  }
}
APY format varies by protocol. Most return decimals (e.g., 0.0485 = 4.85%). Fluid returns percentages directly (e.g., 4.85 = 4.85%). See Protocols Overview for details.

Lending & borrowing summary

Get supply/borrow positions with health metrics from lending protocols:
query {
  walletPositions(inputs: [
    { protocol: "aave",     chainId: 1, walletAddress: "0x..." }
    { protocol: "compound", chainId: 1, walletAddress: "0x..." }
    { protocol: "morpho",   chainId: 1, walletAddress: "0x..." }
  ]) {
    data {
      ... on AaveWalletPositions {
        protocol
        marketStates { netWorth healthFactor totalCollateralBase totalDebtBase }
        supplyPositions { currency { symbol } balanceUsd apy { formatted } isCollateral }
        borrowPositions { currency { symbol } debtUsd apy { formatted } }
      }
      ... on CompoundWalletPositions {
        protocol
        supplyPositions { baseAsset { symbol } balanceUsd apr }
        borrowPositions { baseAsset { symbol } debtUsd apr }
        collateralPositions { asset { symbol } balanceUsd }
        rewardPositions { rewardToken { symbol } accruedUsd }
      }
      ... on MorphoWalletPositions {
        protocol
        marketPositions {
          loanAsset { symbol }
          collateralAsset { symbol }
          supply { assetsUsd }
          borrow { assetsUsd }
          marketMetrics { supplyApy borrowApy lltv utilization }
        }
      }
    }
    errors { protocol error { code message } }
  }
}

Cross-chain positions for one protocol

Check a wallet’s Aave positions across all supported chains:
query {
  walletPositions(inputs: [
    { protocol: "aave", chainId: 1,     walletAddress: "0x..." }
    { protocol: "aave", chainId: 8453,  walletAddress: "0x..." }
    { protocol: "aave", chainId: 42161, walletAddress: "0x..." }
    { protocol: "aave", chainId: 10,    walletAddress: "0x..." }
    { protocol: "aave", chainId: 43114, walletAddress: "0x..." }
  ]) {
    data {
      ... on AaveWalletPositions {
        protocol
        chainId
        marketStates { marketName netWorth healthFactor }
        supplyPositions { currency { symbol } balanceUsd }
        borrowPositions { currency { symbol } debtUsd }
      }
    }
    errors { protocol chainId error { code message retryable } }
  }
}

Pool & market data

Fetch pool-level details for specific vaults or markets. The data field is a JSON string — parse it to access the typed object.
Pass a vault address (42 characters) to get vault pool data:
query {
  poolDetails(inputs: [
    { protocol: "morpho", chainId: 1, poolAddress: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb" }
  ]) {
    data { protocol chainId poolAddress data }
    errors { protocol error { code message } }
  }
}
Parsed data field:
{
  "type": "morpho-vault-pool",
  "name": "Morpho Blue USDC",
  "symbol": "mbUSDC",
  "apy": 0.072,
  "netApy": 0.068,
  "totalAssetsUsd": 52000000.0
}
The data field in poolDetails responses is a JSON string. Parse it with JSON.parse() before accessing its properties.

Handling partial failures

When one protocol fails, the others still return data. Always check both data and errors:
const response = await fetch("https://api.definitiv.io/graphql", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": "pk_your_api_key_here"
  },
  body: JSON.stringify({
    query: `{
      walletPositions(inputs: [
        { protocol: "morpho", chainId: 1, walletAddress: "0x..." }
        { protocol: "aave",   chainId: 1, walletAddress: "0x..." }
      ]) {
        data {
          ... on MorphoWalletPositions { protocol vaultV2Positions { vaultName assetsUsd } }
          ... on AaveWalletPositions   { protocol supplyPositions { currency { symbol } balanceUsd } }
        }
        errors { protocol error { code message retryable } }
      }
    }`
  })
});

const { data } = await response.json();
const { data: positions, errors } = data.walletPositions;

// Process successful results
for (const position of positions) {
  console.log(`${position.protocol}: OK`);
}

// Handle failures
for (const err of errors) {
  if (err.error.retryable) {
    console.log(`${err.protocol}: failed (retryable) — ${err.error.message}`);
  } else {
    console.log(`${err.protocol}: failed — ${err.error.message}`);
  }
}