# Reference to another record.
type Reference {
    id:         String!         # ID of linked record.
}

# Reference to another record.
input ReferenceInput {
    id:         String!
}

# Bonds contain funds that are used to pay rent on record registration and renewal.
type Bond {
    id:         String!         # Primary key, auto-generated by the server.
    owner:      String!         # Bond owner cosmos-sdk address.
    balance:    [Coin!]         # Current balance for each coin type.
}

# OwnerBonds contains the bonds related the owner
type OwnerBonds {
    owner: String!
    bonds: [Bond!]
}

# Mutations require payment in coins (e.g. 100wire).
# Used by the wallet to get the account balance for display and mutations.
type Coin {
    type:       String!         # e.g. 'WIRE'
    quantity:   String!         # e.g. 1000000
}
# Represents an account on the blockchain.
# Mutations have to be signed by a particular account.
type Account {
    address:  String!           # Blockchain address.
    pubKey:   String            # Public key.
    number:   String!           # Account number.
    sequence: String!           # Sequence number used to prevent replays.
    balance:  [Coin!]           # Current balance for each coin type.
}

# Value of a given type.
type Value {
    null:       Boolean

    int:        Int
    float:      Float
    string:     String
    boolean:    Boolean
    json:       String

    reference:  Reference

    values:     [Value]
}
# Value of a given type used as input to queries.
input ValueInput {
    null:       Boolean

    int:        Int
    float:      Float
    string:     String
    boolean:    Boolean

    reference:  ReferenceInput

    values:     [ValueInput]
}

# Key/value pair.
type KeyValue {
    key:        String!
    value:      Value!
}

# Key/value pair for inputs.
input KeyValueInput {
    key:        String!
    value:      ValueInput!
}

# Status information about a node (https://docs.tendermint.com/master/rpc/#/Info/status).
type NodeInfo {
    id:         String!         # Tendermint Node ID.
    network:    String!         # Name of the network/blockchain.
    moniker:    String!         # Name of the node.
}

# Node sync status.
type SyncInfo {
    latest_block_hash:    String!
    latest_block_height:  String!
    latest_block_time:    String!
    catching_up:          Boolean!
}

# Validator set info (https://docs.tendermint.com/master/rpc/#/Info/validators).
type ValidatorInfo {
    address:            String!
    voting_power:       String!
    proposer_priority:  String
}

# Network/peer info (https://docs.tendermint.com/master/rpc/#/Info/net_info).
type PeerInfo {
    node:           NodeInfo!
    is_outbound:    Boolean!
    remote_ip:      String!
}

# Vulcanize chiba-clonk status.
type Status {
    version:    String!
    node:       NodeInfo!
    sync:       SyncInfo!
    validator:  ValidatorInfo
    validators: [ValidatorInfo]!
    num_peers:  String!
    peers:      [PeerInfo]
    disk_usage: String!
}


# An auction bid.
type AuctionBid {
    bidderAddress:  String!
    status:         String!
    commitHash:     String!
    commitTime:     String!
    commitFee:      Coin!
    revealTime:     String!
    revealFee:      Coin!
    bidAmount:      Coin!
}

# A sealed-bid, 2nd price auction.
type Auction {
    id:             String!             # Auction ID.
    status:         String!             # Auction status (commit, reveal, expired).
    ownerAddress:   String!             # Auction owner time.
    createTime:     String!             # Create time.
    commitsEndTime: String!             # Commit phase end time.
    revealsEndTime: String!             # Reveal phase end time.
    commitFee:      Coin!               # Fee required to bid/participate in the auction.
    revealFee:      Coin!               # Reveal fee (paid back to bidders only if they unseal/reveal the bid).
    minimumBid:     Coin!               # Minimum bid amount.
    winnerAddress:  String!             # Winner address.
    winnerBid:      Coin!               # The winning bid amount.
    winnerPrice:    Coin!               # The price that the winner actually pays (2nd highest bid).
    bids:           [AuctionBid]        # Bids make in the auction.
}


# Record defines the basic properties of an entity in the graph database.
type Record {
    id:         String!         # Computed attribute: Multibase encoded content hash (https://github.com/multiformats/multibase).
    names:      [String!]       # Names pointing to this CID (reverse lookup).

    bondId:     String!         # Associated bond ID.
    createTime: String!         # Record create time.
    expiryTime: String!         # Record expiry time.

    owners:     [String!]      # Addresses of record owners.
    attributes: [KeyValue]      # Record attributes.
    references: [Record]        # Record references.
}

# Name authority record.
type AuthorityRecord {
    ownerAddress:     String!   # Owner address.
    ownerPublicKey:   String!   # Owner public key.
    height:           String!   # Height at which record was created.
    status:           String!   # Status (active, auction, expired).
    bondId:           String!   # Associated bond ID.
    expiryTime:       String!   # Authority expiry time.
    auction:          Auction   # Authority auction.
}

# Name record entry, created at a particular height.
type NameRecordEntry {
    id:         String!         # Target record ID.
    height:     String!         # Height at which record was created.
}

# Name record stores the latest and historical name -> record ID mappings.
type NameRecord {
    latest:     NameRecordEntry!     # Latest mame record entry.
    history:    [NameRecordEntry]    # Historical name record entries.
}

type Query {
    #
    # Status API.
    #
    getStatus: Status!

    # Get blockchain accounts.
    getAccounts(
        addresses: [String!]
    ): [Account]

    # Get bonds by IDs.
    getBondsByIds(
        ids: [String!]
    ): [Bond]

    # Query bonds.
    queryBonds(
        attributes: [KeyValueInput]
    ): [Bond]

    # Query bonds by owner.
    queryBondsByOwner(
        ownerAddresses: [String!]
    ): [OwnerBonds]

    #
    # GraphDB API.
    #

    # Get records by IDs.
    getRecordsByIds(
        ids: [String!]
    ): [Record]

    # Query records.
    queryRecords(
        # Multiple attribute conditions are in a logical AND.
        attributes: [KeyValueInput]

        # Whether to query all records, not just named ones (false by default).
        all: Boolean
    ): [Record]

    #
    # Naming API.
    #

    # Lookup authority information.
    lookupAuthorities(
        names: [String!]
    ): [AuthorityRecord]!

    # Lookup name to record mapping information.
    lookupNames(
        names: [String!]
    ): [NameRecord]!

    # Resolve names to records.
    resolveNames(
        names: [String!]
    ): [Record]!

    #
    # Auctions API.
    #

    # Get auctions by IDs.
    getAuctionsByIds(
        ids: [String!]
    ): [Auction]
}