Skip to main content
If GraphiQL is enabled on your endpoint, use the built-in schema explorer for an interactive view of all types.

Shared types

These types are used across all protocols.
type TokenInfo {
  address: String!   # Token contract address
  symbol: String!    # Token ticker symbol (e.g. USDC, WETH)
  decimals: Int!     # Decimal places for the token's smallest unit
}

type ErrorDetail {
  code: String!      # Machine-readable error code
  message: String!   # Human-readable error description
  retryable: Boolean! # Whether the client should retry
}

type ProtocolError {
  protocol: String!
  chainId: Int!
  walletAddress: String!
  error: ErrorDetail!
}

type PoolProtocolError {
  protocol: String!
  chainId: Int!
  poolAddress: String!
  error: ErrorDetail!
}

Query types

input PositionInput {
  protocol: String!      # Protocol identifier
  chainId: Int!          # Blockchain network ID
  walletAddress: String! # Wallet address (hex)
}

input PoolInput {
  protocol: String!
  chainId: Int!
  poolAddress: String!   # Pool/market contract address (hex)
}

type MultiPositionResponse {
  data: [WalletPositionResult!]!
  errors: [ProtocolError!]!
}

type MultiPoolResponse {
  data: [PoolOutput!]!
  errors: [PoolProtocolError!]!
}

type PoolOutput {
  protocol: String!
  chainId: Int!
  poolAddress: String!
  data: String!          # JSON-serialized protocol-native data
}

union WalletPositionResult =
  | MorphoWalletPositions
  | PendleWalletPositions
  | AaveWalletPositions
  | NeutrlWalletPositions
  | AvantisWalletPositions
  | AvantWalletPositions
  | FluidWalletPositions
  | MidasWalletPositions
  | CompoundWalletPositions

Protocol-specific types

type MorphoWalletPositions {
  protocol: String!
  walletAddress: String!
  chainId: Int!
  vaultV1Positions: [MorphoVaultV1Position!]!
  vaultV2Positions: [MorphoVaultV2Position!]!
  marketPositions: [MorphoMarketPosition!]!
}

type MorphoVaultV1Position {
  type: String!
  vaultAddress: String!
  vaultName: String!
  vaultSymbol: String!
  shares: String!            # Vault shares held
  assets: String!            # Underlying assets redeemable
  assetsUsd: Float!
  apy: Float!                # Current vault APY (decimal)
  underlyingAsset: TokenInfo!
  vaultMetrics: VaultMetrics!
}

type MorphoVaultV2Position {
  type: String!
  vaultAddress: String!
  vaultName: String!
  vaultSymbol: String!
  shares: String!
  assets: String!
  assetsUsd: Float!
  apy: Float!
  underlyingAsset: TokenInfo!
  vaultMetrics: VaultMetrics!
}

type VaultMetrics {
  totalAssets: String!
  totalAssetsUsd: Float!
  totalSupply: String!
}

type MorphoMarketPosition {
  type: String!
  marketId: String!          # Unique market identifier hash
  loanAsset: TokenInfo!
  collateralAsset: TokenInfo
  supply: AssetAmount!
  borrow: AssetAmount!
  collateral: AssetAmount!
  healthFactor: Float        # Null when no debt
  marketMetrics: MarketMetrics!
}

type AssetAmount {
  assets: String!            # Raw token amount (string to avoid precision loss)
  assetsUsd: Float!
}

type MarketMetrics {
  supplyApy: Float!
  borrowApy: Float!
  netSupplyApy: Float!       # Including rewards
  netBorrowApy: Float!       # Including rewards
  lltv: Float!               # Liquidation loan-to-value ratio
  utilization: Float!
}
type AaveWalletPositions {
  protocol: String!
  walletAddress: String!
  chainId: Int!
  marketStates: [AaveMarketState!]!
  supplyPositions: [AaveSupplyPosition!]!
  borrowPositions: [AaveBorrowPosition!]!
  reserves: [AaveReserve!]!
}

type AaveMarketState {
  marketAddress: String!
  marketName: String!
  chainId: Int!
  netWorth: Float!
  healthFactor: Float        # Null if no debt
  totalCollateralBase: Float!
  totalDebtBase: Float!
}

type AaveCurrency {
  address: String!
  symbol: String!
  name: String!
  decimals: Int!
}

type AaveBalance {
  value: String!             # Human-readable (e.g. "1234.56")
  raw: String!               # Raw wei value
  decimals: Int!
}

type AaveApy {
  value: Float!              # Decimal (e.g. 0.0532)
  formatted: String!         # Percentage string (e.g. "5.32%")
}

type AaveSupplyPosition {
  type: String!
  marketAddress: String!
  marketName: String!
  chainId: Int!
  currency: AaveCurrency!
  balance: AaveBalance!
  balanceUsd: Float!
  apy: AaveApy!
  isCollateral: Boolean!
  canBeCollateral: Boolean!
}

type AaveBorrowPosition {
  type: String!
  marketAddress: String!
  marketName: String!
  chainId: Int!
  currency: AaveCurrency!
  debt: AaveBalance!
  debtUsd: Float!
  apy: AaveApy!
}

type AaveReserve {
  underlyingTokenAddress: String!
  aToken: AaveTokenMeta!
  vToken: AaveTokenMeta!
}

type AaveTokenMeta {
  address: String!
  symbol: String!
  name: String!
  decimals: Int!
}
type PendleWalletPositions {
  protocol: String!
  walletAddress: String!
  chainId: Int!
  ptPositions: [PendlePTPosition!]!
  ytPositions: [PendleYTPosition!]!
  lpPositions: [PendleLPPosition!]!
  syPositions: [PendleSYPosition!]!
}

type PendlePTPosition {
  type: String!
  marketAddress: String!
  chainId: Int!
  ptToken: TokenInfo!
  underlyingAsset: TokenInfo!
  balance: String!
  balanceUsd: Float!
  impliedApy: Float!         # Current market implied fixed APY
  lockedApy: Float           # User's actual locked APY (null if no history)
  expiryDate: String!        # ISO 8601 maturity date
  ptDiscount: Float!         # Discount vs underlying (e.g. 0.03 = 3%)
}

type PendleYTPosition {
  type: String!
  marketAddress: String!
  chainId: Int!
  ytToken: TokenInfo!
  underlyingAsset: TokenInfo!
  balance: String!
  balanceUsd: Float!
  impliedApy: Float!
  expiryDate: String!
  accruedInterest: Float!    # Unclaimed interest in underlying units
}

type PendleLPPosition {
  type: String!
  marketAddress: String!
  chainId: Int!
  lpToken: TokenInfo!
  underlyingAsset: TokenInfo!
  balance: String!
  balanceUsd: Float!
  lpApy: Float!              # LP APY (fees + yield)
  impliedApy: Float!
  expiryDate: String!
}

type PendleSYPosition {
  type: String!
  syTokenAddress: String!
  chainId: Int!
  syToken: TokenInfo!
  underlyingAsset: TokenInfo!
  balance: String!
  balanceUsd: Float!
}
type FluidWalletPositions {
  protocol: String!
  walletAddress: String!
  chainId: Int!
  lendingPositions: [FluidLendingPosition!]!
  vaultPositions: [FluidVaultPosition!]!
}

type FluidLendingPosition {
  type: String!
  chainId: Int!
  fTokenAddress: String!
  fTokenSymbol: String!
  underlyingAsset: TokenInfo!
  balance: String!
  balanceUnderlying: String!
  balanceUsd: Float!
  apy: Float!                # Percentage value (4.85 = 4.85%)
  rewards: [FluidReward!]!
}

type FluidReward {
  tokenAddress: String!
  tokenSymbol: String!
  rate: String!
  endTime: Float!            # Unix timestamp
  rewardType: String!        # "supply" or "borrow"
}

type FluidVaultPosition {
  type: String!
  chainId: Int!
  vaultAddress: String!
  nftId: String!             # Unique NFT ID for this position
  owner: String!
  isLiquidated: Boolean!
  isSmartCol: Boolean!       # Multi-asset collateral via DEX
  isSmartDebt: Boolean!      # Multi-asset debt via DEX
  supply: String!
  borrow: String!
  supplyToken: TokenInfo!
  supplyToken1: TokenInfo    # Null for standard vaults
  borrowToken: TokenInfo!
  borrowToken1: TokenInfo    # Null for standard vaults
  collateralFactor: Float!   # Percentage (0-100)
  liquidationThreshold: Float! # Percentage (0-100)
  supplyRateVault: String!
  borrowRateVault: String!
  # Smart vault fields (null when not applicable)
  supplyToken0Amount: String
  supplyToken1Amount: String
  borrowToken0Amount: String
  borrowToken1Amount: String
  dexSupplyRate0: String
  dexSupplyRate1: String
  dexBorrowRate0: String
  dexBorrowRate1: String
}
type CompoundWalletPositions {
  protocol: String!
  walletAddress: String!
  chainId: Int!
  supplyPositions: [CompoundSupplyPosition!]!
  borrowPositions: [CompoundBorrowPosition!]!
  collateralPositions: [CompoundCollateralPosition!]!
  rewardPositions: [CompoundRewardPosition!]!
}

type CompoundSupplyPosition {
  type: String!              # "compound-supply"
  marketAddress: String!
  baseAsset: TokenInfo!
  balance: String!           # Raw bigint string
  balanceUsd: Float!
  apr: Float!                # Annualized rate (not compounded)
}

type CompoundBorrowPosition {
  type: String!              # "compound-borrow"
  marketAddress: String!
  baseAsset: TokenInfo!
  debt: String!
  debtUsd: Float!
  apr: Float!
}

type CompoundCollateralPosition {
  type: String!              # "compound-collateral"
  marketAddress: String!
  asset: TokenInfo!
  balance: String!
  balanceUsd: Float!
}

type CompoundRewardPosition {
  type: String!              # "compound-reward"
  marketAddress: String!
  rewardToken: TokenInfo!
  accrued: String!           # Formatted with token decimals
  accruedUsd: Float!
}
These three protocols share a similar structure.
# Neutrl
type NeutrlWalletPositions {
  protocol: String!
  walletAddress: String!
  chainId: Int!
  vaultPosition: NeutrlVaultPosition  # Null if no position
}

type NeutrlVaultPosition {
  type: String!
  vaultAddress: String!
  underlyingAsset: TokenInfo!
  balance: String!
  balanceUsd: Float!
  apy: Float                          # Null if not yet calculable
  exchangeRate: Float!
  vaultMetrics: NeutrlVaultMetrics!
}

type NeutrlVaultMetrics {
  totalAssets: String!
  totalSupply: String!
  decimals: Int!
}

# Avantis (same shape as Neutrl)
type AvantisWalletPositions { ... }
type AvantisVaultPosition { ... }
type AvantisVaultMetrics { ... }

# Avant (same shape as Neutrl)
type AvantWalletPositions { ... }
type AvantVaultPosition { ... }
type AvantVaultMetrics { ... }
type MidasWalletPositions {
  protocol: String!
  walletAddress: String!
  chainId: Int!
  tokenPositions: [MidasTokenPosition!]!
}

type MidasTokenPosition {
  type: String!
  tokenAddress: String!
  symbol: String!            # e.g. "mHYPER"
  decimals: Int!
  balance: String!
  balanceUsd: Float!
  apy: Float                 # Null if not available
  oraclePrice: Float!        # From Chainlink-compatible feed
}