clp-feed-interface 0.1.1

Interface package for querying the CLP Feed oracle contract
Documentation
# clp-feed-interface

Interface package for querying the **Coreum Lending Protocol (CLP) Feed** oracle contract. This package provides type-safe bindings for interacting with the CLP Feed price oracle, which aggregates validator-signed price data for various assets.

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
clp-feed-interface = "0.1.0"
cosmwasm-std = "2.2"
```

## Quick Start

### Using the Helper Querier (Recommended)

```rust
use cosmwasm_std::{Deps, Addr, StdResult};
use clp_feed_interface::ClpFeedQuerier;

// In your contract's execute or query function
pub fn get_price(deps: Deps, oracle_addr: Addr, denom: String) -> StdResult<String> {
    let oracle = ClpFeedQuerier::new(&deps.querier, oracle_addr);
    
    let response = oracle.query_price_by_denom(denom)?;
    
    match response.price {
        Some(price_data) => Ok(price_data.price),
        None => Err(cosmwasm_std::StdError::generic_err("Price not found")),
    }
}
```

### Direct Query

```rust
use cosmwasm_std::{Deps, Addr, StdResult};
use clp_feed_interface::{QueryMsg, AggregatedPriceResponse};

pub fn query_price(deps: Deps, oracle_addr: Addr, asset: String) -> StdResult<AggregatedPriceResponse> {
    deps.querier.query_wasm_smart(
        oracle_addr.to_string(),
        &QueryMsg::GetPrice { asset },
    )
}
```

## Available Queries

### Price Queries

#### `GetPrice`
Get the current aggregated price for an asset by name.

```rust
use clp_feed_interface::QueryMsg;

let query = QueryMsg::GetPrice { 
    asset: "ATOM".to_string() 
};
```

#### `GetPriceByDenom`
Get the current aggregated price for a denom (e.g., "uatom").

```rust
let query = QueryMsg::GetPriceByDenom { 
    denom: "uatom".to_string() 
};
```

#### `GetAllPrices`
Get all current aggregated prices.

```rust
let query = QueryMsg::GetAllPrices {};
```

### Validator Queries

#### `GetValidator`
Get information about a specific validator.

```rust
let query = QueryMsg::GetValidator { 
    validator_id: "validator1".to_string() 
};
```

#### `GetAllValidators`
Get all registered validators.

```rust
let query = QueryMsg::GetAllValidators {};
```

### Configuration Queries

#### `GetConfig`
Get contract configuration (min signatures, max price age).

```rust
let query = QueryMsg::GetConfig {};
```

#### `GetAdmin`
Get the admin address.

```rust
let query = QueryMsg::GetAdmin {};
```

#### `GetOperators`
Get all operator addresses.

```rust
let query = QueryMsg::GetOperators {};
```

#### `GetDenomExists`
Check if a denom is configured.

```rust
let query = QueryMsg::GetDenomExists { 
    denom: "uatom".to_string() 
};
```

#### `GetRecentSubmission`
Get a recent price submission from a specific validator.

```rust
let query = QueryMsg::GetRecentSubmission {
    asset: "ATOM".to_string(),
    validator_id: "validator1".to_string(),
};
```

## Type Definitions

### `AggregatedPrice`

The main price data structure returned by the oracle:

```rust
pub struct AggregatedPrice {
    pub asset: String,                    // Asset symbol (e.g., "ATOM")
    pub price: String,                    // Price as string
    pub timestamp: Timestamp,              // Last update timestamp
    pub deviation: Option<String>,         // Standard deviation (optional)
    pub submissions: Vec<PriceSubmission>, // Individual validator submissions
    pub feed_block_height: u64,            // Oracle feed block height
    pub chain_block_height: Option<u64>,   // Chain block height (optional)
}
```

### `PriceSubmission`

Individual validator price submission:

```rust
pub struct PriceSubmission {
    pub validator_id: String,
    pub asset: String,
    pub price: String,
    pub timestamp: u64,        // Unix timestamp in seconds
    pub sources: Vec<String>,  // Price data sources
    pub signature: String,    // Ed25519 signature (hex-encoded)
}
```

### `ValidatorInfo`

Validator information:

```rust
pub struct ValidatorInfo {
    pub public_key: String,  // Ed25519 public key (hex-encoded)
    pub active: bool,        // Whether validator is active
}
```

## Complete Example

```rust
use cosmwasm_std::{Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128};
use clp_feed_interface::{ClpFeedQuerier, AggregatedPriceResponse};

pub fn execute_trade(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    collateral_denom: String,
    amount: Uint128,
) -> StdResult<Response> {
    // Load your contract's config (which should store the oracle address)
    let config = CONFIG.load(deps.storage)?;
    
    // Query the oracle for collateral price
    let oracle = ClpFeedQuerier::new(&deps.querier, config.oracle_address);
    let price_response = oracle.query_price_by_denom(collateral_denom.clone())?;
    
    // Extract price data
    let price_data = price_response.price
        .ok_or_else(|| cosmwasm_std::StdError::generic_err("Price not available"))?;
    
    // Validate price freshness (optional)
    let price_age = env.block.time.seconds() - price_data.timestamp.seconds();
    if price_age > 300 {
        return Err(cosmwasm_std::StdError::generic_err("Price data too old"));
    }
    
    // Use the price in your logic
    let price_value = price_data.price.parse::<f64>()
        .map_err(|_| cosmwasm_std::StdError::generic_err("Invalid price format"))?;
    
    // Your trading logic here...
    
    Ok(Response::new()
        .add_attribute("action", "trade")
        .add_attribute("price_used", price_data.price)
        .add_attribute("price_timestamp", price_data.timestamp.seconds().to_string()))
}
```

## Response Types

All query responses are strongly typed:

- `AggregatedPriceResponse` - Contains `Option<AggregatedPrice>`
- `AllPricesResponse` - Contains `Vec<AggregatedPrice>`
- `ValidatorInfoResponse` - Contains validator ID and `Option<ValidatorInfo>`
- `AllValidatorsResponse` - Contains `Vec<(String, ValidatorInfo)>`
- `PriceSubmissionResponse` - Contains `Option<PriceSubmission>`
- `ConfigResponse` - Contains `min_signatures: u32` and `max_price_age: u64`
- `AdminResponse` - Contains `admin: Addr`
- `OperatorsResponse` - Contains `operators: Vec<Addr>`
- `DenomExistsResponse` - Contains `exists: bool` and `asset: Option<AssetInfo>`

## Deployed Contracts

### Mainnet
- **Contract Address**: `TBD` (Update after deployment)

### Testnet
- **Contract Address**: `TBD` (Update after deployment)

## Version Compatibility

| clp-feed-interface | clp-feed Contract | Status |
|-------------------|-------------------|--------|
| 0.1.0 | 0.1.0 | ✅ Compatible |

## Features

- **Type-safe** - Full Rust type definitions for all queries and responses
-**Lightweight** - Minimal dependencies (only CosmWasm standard libraries)
-**Helper functions** - Convenient `ClpFeedQuerier` wrapper
-**Well-documented** - Comprehensive inline documentation
-**Schema support** - Compatible with CosmWasm schema generation

## Error Handling

The oracle may return `None` for prices in certain cases:
- Asset/denom not configured
- No price data available yet
- Price data expired

Always check for `None` values:

```rust
let response = oracle.query_price_by_denom("uatom".to_string())?;

match response.price {
    Some(price) => {
        // Use price
    },
    None => {
        // Handle missing price
        return Err(cosmwasm_std::StdError::generic_err("Price not available"));
    }
}
```

## License

MIT

## Links

- [Repository]https://github.com/your-org/coreum_lending_protocol
- [Documentation]https://docs.rs/clp-feed-interface
- [Coreum Lending Protocol]https://github.com/your-org/coreum_lending_protocol