[hermes] Add docs for 1 method (#995)

* doc this one method

* revert
This commit is contained in:
Jayant Krishnamurthy 2023-07-29 21:11:03 -07:00 committed by GitHub
parent 7674a3a07c
commit 07b01118d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 34 deletions

View File

@ -35,14 +35,23 @@ To set up and run a Hermes node, follow the steps below:
```
This will create a binary in the target/release directory.
5. **Run the node**: To run Hermes for Pythnet, use the following command:
```bash
./target/release/hermes run \
--pythnet-http-endpoint https://pythnet-rpc/ \
--pythnet-ws-endpoint wss://pythnet-rpc/
```
Your Hermes node will now start and connect to the specified networks. You
can interact with the node using the REST and Websocket APIs on port 33999.
For local development, you can also run the node with cargo watch to restart
it automatically when the code changes:
```bash
cargo watch -w src -x "run -- run --pythnet-http-endpoint https://pythnet.rpcpool.com --pythnet-ws-endpoint wss://pythnet.rpcpool.com"
```
## Architecture Overview
For users who simply want to run the software, this section can be skipped.

View File

@ -3,24 +3,18 @@ use {
crate::store::Store,
anyhow::Result,
axum::{
extract::Extension,
routing::get,
Router,
},
serde_qs::axum::QsQueryConfig,
std::sync::Arc,
tokio::{
signal,
sync::mpsc::Receiver,
},
tower_http::cors::CorsLayer,
utoipa::{
openapi::security::{
ApiKey,
ApiKeyValue,
SecurityScheme,
},
Modify,
OpenApi,
},
utoipa::OpenApi,
utoipa_swagger_ui::SwaggerUi,
};
@ -54,7 +48,7 @@ pub async fn run(store: Arc<Store>, mut update_rx: Receiver<()>, rpc_addr: Strin
rest::latest_price_feeds,
),
components(
schemas(types::RpcPriceFeedMetadata, types::RpcPriceFeed)
schemas(types::RpcPriceFeedMetadata, types::RpcPriceFeed, types::PriceIdInput)
),
tags(
(name = "hermes", description = "Pyth Real-Time Pricing API")
@ -80,7 +74,11 @@ pub async fn run(store: Arc<Store>, mut update_rx: Receiver<()>, rpc_addr: Strin
.route("/api/get_vaa_ccip", get(rest::get_vaa_ccip))
.route("/api/price_feed_ids", get(rest::price_feed_ids))
.with_state(state.clone())
.layer(CorsLayer::permissive()); // Permissive CORS layer to allow all origins
// Permissive CORS layer to allow all origins
.layer(CorsLayer::permissive())
// non-strict mode permits escaped [] in URL parameters.
// 5 is the allowed depth (also the default value for this parameter).
.layer(Extension(QsQueryConfig::new(false)));
// Call dispatch updates to websocket every 1 seconds

View File

@ -97,26 +97,34 @@ pub async fn latest_vaas(
}
#[derive(Debug, serde::Deserialize, IntoParams)]
#[into_params(parameter_in=Query)]
pub struct LatestPriceFeedsQueryParams {
#[param(value_type = String)]
/// Get the most recent price update for these price feed ids.
/// Provide this parameter multiple times to retrieve multiple price updates,
/// ids[]=a12...&ids[]=b4c...
#[param(
rename = "ids[]",
example = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43"
)]
ids: Vec<PriceIdInput>,
/// If true, include the `metadata` field in the response with additional metadata about
/// the price update.
#[serde(default)]
#[param(value_type = Option<bool>, required = false, nullable = true)]
verbose: bool,
/// If true, include the binary price update in the `vaa` field of each returned feed.
/// This binary data can be submitted to Pyth contracts to update the on-chain price.
#[serde(default)]
#[param(value_type = Option<bool>, required = false, nullable = true)]
binary: bool,
}
/// Get the latest prices by price feed ids.
///
/// Get the latest price updates for a provided collection of price feed ids.
/// Get the latest price updates by price feed id.
///
/// Given a collection of price feed ids, retrieve the latest Pyth price for each price feed.
#[utoipa::path(
get,
path = "/api/latest_price_feeds",
responses(
(status = 200, description = "Price feeds retrieved successfully", body = [Vec<RpcPriceFeed>])
(status = 200, description = "Price updates retrieved successfully", body = [Vec<RpcPriceFeed>])
),
params(
LatestPriceFeedsQueryParams

View File

@ -19,23 +19,21 @@ use {
Price,
PriceIdentifier,
},
utoipa::{
openapi::{
RefOr,
Schema,
},
IntoParams,
ToSchema,
},
utoipa::ToSchema,
wormhole_sdk::Chain,
};
/// PriceIdInput is a wrapper around a 32-byte hex string.
/// that supports a flexible deserialization from a hex string.
/// It supports both 0x-prefixed and non-prefixed hex strings,
/// and also supports both lower and upper case characters.
#[derive(Debug, Clone, Deref, DerefMut)]
/// A price id is a 32-byte hex string, optionally prefixed with "0x".
/// Price ids are case insensitive.
///
/// Examples:
/// * 0x63f341689d98a12ef60a5cff1d7f85c70a9e17bf1575f0e7c0b2512d48b1c8b3
/// * 63f341689d98a12ef60a5cff1d7f85c70a9e17bf1575f0e7c0b2512d48b1c8b3
///
/// See https://pyth.network/developers/price-feed-ids for a list of all price feed ids.
#[derive(Debug, Clone, Deref, DerefMut, ToSchema)]
#[schema(value_type=String)]
pub struct PriceIdInput([u8; 32]);
// TODO: Use const generics instead of macro.
impl_deserialize_for_hex_string_wrapper!(PriceIdInput, 32);
@ -50,15 +48,17 @@ type Base64String = String;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct RpcPriceFeedMetadata {
#[schema(value_type = u64)]
#[schema(value_type = u64, example=85480034)]
pub slot: Slot,
#[schema(example = 26)]
pub emitter_chain: u16,
#[schema(value_type = i64)]
#[schema(value_type = i64, example=1690576641)]
pub price_service_receive_time: UnixTimestamp,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct RpcPriceFeed {
#[schema(example = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43")]
pub id: PriceIdentifier,
pub price: Price,
pub ema_price: Price,
@ -66,7 +66,7 @@ pub struct RpcPriceFeed {
pub metadata: Option<RpcPriceFeedMetadata>,
/// Vaa binary represented in base64.
#[serde(skip_serializing_if = "Option::is_none")]
#[schema(value_type = Option<String>)]
#[schema(value_type = Option<String>, example="UE5BVQEAAAADuAEAAAADDQC1H7meY5fTed0FsykIb8dt+7nKpbuzfvU2DplDi+dcUl8MC+UIkS65+rkiq+zmNBxE2gaxkBkjdIicZ/fBo+X7AAEqp+WtlWb84np8jJfLpuQ2W+l5KXTigsdAhz5DyVgU3xs+EnaIZxBwcE7EKzjMam+V9rlRy0CGsiQ1kjqqLzfAAQLsoVO0Vu5gVmgc8XGQ7xYhoz36rsBgMjG+e3l/B01esQi/KzPuBf/Ar8Sg5aSEOvEU0muSDb+KIr6d8eEC+FtcAAPZEaBSt4ysXVL84LUcJemQD3SiG30kOfUpF8o7/wI2M2Jf/LyCsbKEQUyLtLbZqnJBSfZJR5AMsrnHDqngMLEGAAY4UDG9GCpRuPvg8hOlsrXuPP3zq7yVPqyG0SG+bNo8rEhP5b1vXlHdG4bZsutX47d5VZ6xnFROKudx3T3/fnWUAQgAU1+kUFc3e0ZZeX1dLRVEryNIVyxMQIcxWwdey+jlIAYowHRM0fJX3Scs80OnT/CERwh5LMlFyU1w578NqxW+AQl2E/9fxjgUTi8crOfDpwsUsmOWw0+Q5OUGhELv/2UZoHAjsaw9OinWUggKACo4SdpPlHYldoWF+J2yGWOW+F4iAQre4c+ocb6a9uSWOnTldFkioqhd9lhmV542+VonCvuy4Tu214NP+2UNd/4Kk3KJCf3iziQJrCBeLi1cLHdLUikgAQtvRFR/nepcF9legl+DywAkUHi5/1MNjlEQvlHyh2XbMiS85yu7/9LgM6Sr+0ukfZY5mSkOcvUkpHn+T+Nw/IrQAQ7lty5luvKUmBpI3ITxSmojJ1aJ0kj/dc0ZcQk+/qo0l0l3/eRLkYjw5j+MZKA8jEubrHzUCke98eSoj8l08+PGAA+DAKNtCwNZe4p6J1Ucod8Lo5RKFfA84CPLVyEzEPQFZ25U9grUK6ilF4GhEia/ndYXLBt3PGW3qa6CBBPM7rH3ABGAyYEtUwzB4CeVedA5o6cKpjRkIebqDNSOqltsr+w7kXdfFVtsK2FMGFZNt5rbpIR+ppztoJ6eOKHmKmi9nQ99ARKkTxRErOs9wJXNHaAuIRV38o1pxRrlQRzGsRuKBqxcQEpC8OPFpyKYcp6iD5l7cO/gRDTamLFyhiUBwKKMP07FAWTEJv8AAAAAABrhAfrtrFhR4yubI7X5QRqMK6xKrj7U3XuBHdGnLqSqcQAAAAAAGp0GAUFVV1YAAAAAAAUYUmIAACcQBsfKUtr4PgZbIXRxRESU79PjE4IBAFUA5i32yLSoX+GmfbRNwS3l2zMPesZrctxliv7fD0pBW0MAAAKqqMJFwAAAAAAqE/NX////+AAAAABkxCb7AAAAAGTEJvoAAAKqIcWxYAAAAAAlR5m4CP/mPsh1IezjYpDlJ4GRb5q4fTs2LjtyO6M0XgVimrIQ4kSh1qg7JKW4gbGkyRntVFR9JO/GNd3FPDit0BK6M+JzXh/h12YNCz9wxlZTvXrNtWNbzqT+91pvl5cphhSPMfAHyEzTPaGR9tKDy9KNu56pmhaY32d2vfEWQmKo22guegeR98oDxs67MmnUraco46a3zEnac2Bm80pasUgMO24=")]
pub vaa: Option<Base64String>,
}