type Account @entity {
  id: Bytes!
  isContract: Boolean!
  asAsset: Asset
  balances: [Balance!]! @derivedFrom(field: "account")
  nativeBalance: BigDecimal!
  nativeBalanceExact: BigInt!
  transferFromEvent: [Event_Transfer!]! @derivedFrom(field: "from")
  transferToEvent: [Event_Transfer!]! @derivedFrom(field: "to")
  blockedAssets: [BlockedAccount!]! @derivedFrom(field: "account")
  roleGranted: [Event_RoleGranted!]! @derivedFrom(field: "account")
  roleRevoked: [Event_RoleRevoked!]! @derivedFrom(field: "account")
}

type BlockedAccount @entity {
  id: Bytes!
  account: Account!
  asset: Asset!
}

type Role @entity(immutable: true) {
  id: Bytes!
  name: String!
  assets: [AssetRole!]! @derivedFrom(field: "role")
}

type AssetRole @entity {
  id: ID!
  asset: Asset!
  role: Role!
  members: [Account!]!
  roleGranted: [Event_RoleGranted!]! @derivedFrom(field: "assetRole")
  roleRevoked: [Event_RoleRevoked!]! @derivedFrom(field: "assetRole")
}

interface Asset {
  id: Bytes!
  asAccount: Account!
  name: String
  symbol: String
  decimals: Int!
  totalSupply: BigDecimal!
  totalSupplyExact: BigInt!
  balances: [Balance!]! @derivedFrom(field: "asset")
  transfers: [Event_Transfer!]! @derivedFrom(field: "emitter")
  roles: [AssetRole!]! @derivedFrom(field: "asset")
}

type Bond implements Asset @entity {
  id: Bytes!
  asAccount: Account!
  name: String
  symbol: String
  decimals: Int!
  totalSupply: BigDecimal!
  totalSupplyExact: BigInt!
  balances: [Balance!]! @derivedFrom(field: "asset")
  transfers: [Event_Transfer!]! @derivedFrom(field: "emitter")
  roles: [AssetRole!]! @derivedFrom(field: "asset")
  isin: String!
  maturityDate: BigInt!
  isMatured: Boolean!
  paused: Boolean!
  faceValue: BigInt!
  underlyingAsset: Bytes!
  redeemedAmount: BigInt!
  redeemedAmountByHolder: [Event_BondRedeemed!]! @derivedFrom(field: "emitter")
  underlyingBalance: BigInt!
  underlyingTransfers: [Event_UnderlyingAssetTransfer!]!
    @derivedFrom(field: "emitter")
}

type Event_BondRedeemed implements BondEvent @entity(immutable: true) {
  id: Bytes!
  emitter: Bond!
  timestamp: BigInt!
  holder: Account!
  bondAmount: BigInt!
  underlyingAmount: BigInt!
}

type Event_UnderlyingAssetTransfer implements BondEvent
  @entity(immutable: true)
{
  id: Bytes!
  emitter: Bond!
  timestamp: BigInt!
  account: Account!
  amount: BigInt! # Positive for top-up, negative for withdrawal
}

type Equity implements Asset @entity {
  id: Bytes!
  asAccount: Account!
  name: String
  symbol: String
  decimals: Int!
  totalSupply: BigDecimal!
  totalSupplyExact: BigInt!
  balances: [Balance!]! @derivedFrom(field: "asset")
  transfers: [Event_Transfer!]! @derivedFrom(field: "emitter")
  roles: [AssetRole!]! @derivedFrom(field: "asset")
  isin: String!
  equityClass: String!
  equityCategory: String!
  paused: Boolean!
}

type StableCoin implements Asset @entity {
  id: Bytes!
  asAccount: Account!
  name: String
  symbol: String
  decimals: Int!
  totalSupply: BigDecimal!
  totalSupplyExact: BigInt!
  balances: [Balance!]! @derivedFrom(field: "asset")
  transfers: [Event_Transfer!]! @derivedFrom(field: "emitter")
  roles: [AssetRole!]! @derivedFrom(field: "asset")
  isin: String
  collateral: BigDecimal!
  collateralExact: BigInt!
  paused: Boolean!
}

type CryptoCurrency implements Asset @entity {
  id: Bytes!
  asAccount: Account!
  name: String
  symbol: String
  decimals: Int!
  totalSupply: BigDecimal!
  totalSupplyExact: BigInt!
  balances: [Balance!]! @derivedFrom(field: "asset")
  transfers: [Event_Transfer!]! @derivedFrom(field: "emitter")
  roles: [AssetRole!]! @derivedFrom(field: "asset")
}

type Balance @entity {
  id: Bytes!
  asset: Asset!
  account: Account!
  value: BigDecimal!
  valueExact: BigInt!
  transferFromEvent: [Event_Transfer!]! @derivedFrom(field: "fromBalance")
  transferToEvent: [Event_Transfer!]! @derivedFrom(field: "toBalance")
}

interface AssetEvent {
  id: Bytes!
  timestamp: BigInt!
  emitter: Asset!
}

interface BondEvent implements AssetEvent {
  id: Bytes!
  timestamp: BigInt!
  emitter: Bond! # Further narrow to Bond type
}

type Event_Transfer implements AssetEvent @entity(immutable: true) {
  id: Bytes!
  emitter: Asset!
  timestamp: BigInt!
  asset: Asset!
  from: Account
  fromBalance: Balance
  to: Account
  toBalance: Balance
  value: BigDecimal!
  valueExact: BigInt!
}

type Event_RoleAdminChanged implements AssetEvent @entity(immutable: true) {
  id: Bytes!
  emitter: Asset!
  timestamp: BigInt!
  role: AssetRole!
  newAdminRole: AssetRole!
  previousAdminRole: AssetRole!
}

type Event_RoleGranted implements AssetEvent @entity(immutable: true) {
  id: Bytes!
  emitter: Asset!
  timestamp: BigInt!
  assetRole: AssetRole!
  account: Account!
  sender: Account!
}

type Event_RoleRevoked implements AssetEvent @entity(immutable: true) {
  id: Bytes!
  emitter: Asset!
  timestamp: BigInt!
  assetRole: AssetRole!
  account: Account!
  sender: Account!
}

# Transfer Activity Time Series
type TransferData @entity(timeseries: true) {
  id: Int8!
  timestamp: Timestamp!
  asset: Asset!
  value: BigDecimal!
  valueExact: BigInt!
  from: Account
  to: Account
}

# Asset Supply Time Series
type AssetSupplyData @entity(timeseries: true) {
  id: Int8!
  timestamp: Timestamp!
  asset: Asset!
  totalSupply: BigDecimal!
  totalSupplyExact: BigInt!
  assetType: String! # "Bond", "Equity", "StableCoin", "CryptoCurrency"
}

# Transfer Activity Aggregations
type TransferStats
  @aggregation(intervals: ["hour", "day"], source: "TransferData")
{
  id: Int8!
  timestamp: Timestamp!
  asset: Asset! # dimension
  totalTransfers: Int8! @aggregate(fn: "count", cumulative: true)
  totalVolume: BigDecimal! @aggregate(fn: "sum", arg: "value")
  totalVolumeExact: BigInt! @aggregate(fn: "sum", arg: "valueExact")
  minTransferValue: BigDecimal! @aggregate(fn: "min", arg: "value")
  minTransferValueExact: BigInt! @aggregate(fn: "min", arg: "valueExact")
  maxTransferValue: BigDecimal! @aggregate(fn: "max", arg: "value")
  maxTransferValueExact: BigInt! @aggregate(fn: "max", arg: "valueExact")
}

# Asset Supply Aggregations
type AssetSupplyStats
  @aggregation(intervals: ["hour", "day"], source: "AssetSupplyData")
{
  id: Int8!
  timestamp: Timestamp!
  asset: Asset! # dimension
  assetType: String! # dimension
  totalSupply: BigDecimal! @aggregate(fn: "last", arg: "totalSupply")
  totalSupplyExact: BigInt! @aggregate(fn: "last", arg: "totalSupplyExact")
  supplyChange: BigDecimal! @aggregate(fn: "sum", arg: "totalSupply")
  supplyChangeExact: BigInt! @aggregate(fn: "sum", arg: "totalSupplyExact")
}

# Account Activity Time Series
type AccountActivityData @entity(timeseries: true) {
  id: Int8!
  timestamp: Timestamp!
  account: Account!
  asset: Asset!
  balance: BigDecimal!
  balanceExact: BigInt!
  isBlocked: Boolean!
  blockedValue: Int! # Numeric field for aggregation
}

# Account Activity Aggregations
type AccountActivityStats
  @aggregation(intervals: ["hour", "day"], source: "AccountActivityData")
{
  id: Int8!
  timestamp: Timestamp!
  account: Account! # dimension
  asset: Asset! # dimension
  minBalance: BigDecimal! @aggregate(fn: "min", arg: "balance")
  minBalanceExact: BigInt! @aggregate(fn: "min", arg: "balanceExact")
  maxBalance: BigDecimal! @aggregate(fn: "max", arg: "balance")
  maxBalanceExact: BigInt! @aggregate(fn: "max", arg: "balanceExact")
  lastBalance: BigDecimal! @aggregate(fn: "last", arg: "balance")
  lastBalanceExact: BigInt! @aggregate(fn: "last", arg: "balanceExact")
  blockedCount: Int8! @aggregate(fn: "sum", arg: "blockedValue")
}

# Role Activity Time Series
type RoleActivityData @entity(timeseries: true) {
  id: Int8!
  timestamp: Timestamp!
  asset: Asset!
  role: Role!
  isGranted: Boolean!
  account: Account!
  grantValue: Int! # Numeric field for aggregation
  revokeValue: Int! # Numeric field for aggregation
  activeValue: Int! # Numeric field for aggregation
}

# Role Activity Aggregations
type RoleActivityStats
  @aggregation(intervals: ["hour", "day"], source: "RoleActivityData")
{
  id: Int8!
  timestamp: Timestamp!
  asset: Asset! # dimension
  role: Role! # dimension
  totalGranted: Int8! @aggregate(fn: "sum", arg: "grantValue")
  totalRevoked: Int8! @aggregate(fn: "sum", arg: "revokeValue")
  activeRoles: Int8! @aggregate(fn: "sum", arg: "activeValue", cumulative: true)
}

# Bond Specific Time Series
type BondMetricsData @entity(timeseries: true) {
  id: Int8!
  timestamp: Timestamp!
  bond: Bond!
  daysToMaturity: Int!
  isMatured: Boolean!
  maturedValue: Int! # Numeric field for aggregation
}

# Bond Metrics Aggregations
type BondMetricsStats
  @aggregation(intervals: ["hour", "day"], source: "BondMetricsData")
{
  id: Int8!
  timestamp: Timestamp!
  minDaysToMaturity: Int! @aggregate(fn: "min", arg: "daysToMaturity")
  maxDaysToMaturity: Int! @aggregate(fn: "max", arg: "daysToMaturity")
  maturedBonds: Int8!
    @aggregate(fn: "sum", arg: "maturedValue", cumulative: true)
}

# StableCoin Metrics Time Series
type StableCoinMetricsData @entity(timeseries: true) {
  id: Int8!
  timestamp: Timestamp!
  stableCoin: StableCoin!
  collateralRatio: BigDecimal!
  collateralRatioExact: BigInt!
}

# StableCoin Metrics Aggregations
type StableCoinMetricsStats
  @aggregation(intervals: ["hour", "day"], source: "StableCoinMetricsData")
{
  id: Int8!
  timestamp: Timestamp!
  stableCoin: StableCoin! # dimension
  minCollateralRatio: BigDecimal! @aggregate(fn: "min", arg: "collateralRatio")
  minCollateralRatioExact: BigInt!
    @aggregate(fn: "min", arg: "collateralRatioExact")
  maxCollateralRatio: BigDecimal! @aggregate(fn: "max", arg: "collateralRatio")
  maxCollateralRatioExact: BigInt!
    @aggregate(fn: "max", arg: "collateralRatioExact")
  lastCollateralRatio: BigDecimal!
    @aggregate(fn: "last", arg: "collateralRatio")
  lastCollateralRatioExact: BigInt!
    @aggregate(fn: "last", arg: "collateralRatioExact")
}

# Equity Category Time Series
type EquityCategoryData @entity(timeseries: true) {
  id: Int8!
  timestamp: Timestamp!
  equity: Equity!
  category: String!
  equityClass: String!
}

# Equity Category Aggregations
type EquityCategoryStats
  @aggregation(intervals: ["hour", "day"], source: "EquityCategoryData")
{
  id: Int8!
  timestamp: Timestamp!
  category: String! # dimension
  equityClass: String! # dimension
  totalEquities: Int8! @aggregate(fn: "count", cumulative: true)
}
