Building with Connect? Join our Discord!

Summary

Connect prices are stored within the x/oracle module.

On very specific chains - right now only dYdX - they live in a different storage module (in dYdX’s case, x/prices).

These prices are updated on a per-block basis when there is a sufficient delta from the last block’s price. They can be accessed natively by CosmWasm smart contracts, other modules, or those with access to chain state.

Connect’s market configuration is stored in the x/marketmap. This module, unlike x/oracle, does not store price data. Instead, it stores which currency pairs are supported and how they are configured.

Getting Supported Assets

Every chain will have a different set of supported assets. You can find out which assets are supported on your chain by either running:

  1. (REST): curl http://localhost:1317/slinky/marketmap/v1/marketmap
  2. (application cli): appd q marketmap marketmap
  3. (gRPC): grpcurl -plaintext localhost:9090 slinky.marketmap.v1.Query/MarketMap

This will return a JSON list of supported assets with associated metadata.

Accessing Connect Prices over node APIs and RPC

To access all Connect prices (as of the last committed block):

  1. (REST): curl http://localhost:1317/slinky/oracle/v1/get_prices
  2. (gRPC): grpcurl -plaintext localhost:9090 slinky.oracle.v1.Query/GetPrices

To get a specific currency pair:

  1. (Get all currency pairs request) appd q oracle currency-pairs
  2. (Get price request) appd q oracle price [base] [quote]

Price Metadata within Connect

When calling getPrices via the above methods, you are returned an array of GetPriceResponse, each of which contains the following metadata about individual prices:

  1. QuotePrice
  2. nonce
  3. decimals
  4. ID

GetPriceResponse looks like this:

query.proto
    // GetPriceResponse is the response from the GetPrice grpc method exposed from
    // the x/oracle query service.

    message GetPriceResponse {
        // QuotePrice represents the quote-price for the CurrencyPair given in
        // GetPriceRequest (possibly nil if no update has been made)
        QuotePrice price = 1 [ (gogoproto.nullable) = true ];
        // nonce represents the nonce for the CurrencyPair if it exists in state
        uint64 nonce = 2;
        // decimals represents the number of decimals that the quote-price is
        // represented in. It is used to scale the QuotePrice to its proper value.
        uint64 decimals = 3;
        // ID represents the identifier for the CurrencyPair.
        uint64 id = 4;
    }

Inside QuotePrice, you can fetch for the currency-pair:

  1. price
  2. timestamp of last update
  3. blockheight of last update

QuotePrice looks like this:

query.proto
    // QuotePrice is the representation of the aggregated prices for a CurrencyPair,
    // where price represents the price of Base in terms of Quote
    message QuotePrice {
    string price = 1 [
        (cosmos_proto.scalar) = "cosmos.Int",
        (gogoproto.customtype) = "cosmossdk.io/math.Int",
        (gogoproto.nullable) = false
    ];

    // BlockTimestamp tracks the block height associated with this price update.
    // We include block timestamp alongside the price to ensure that smart
    // contracts and applications are not utilizing stale oracle prices
    google.protobuf.Timestamp block_timestamp = 2
        [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ];

    // BlockHeight is height of block mentioned above
    uint64 block_height = 3;
    }