diff --git a/anchor/http_api/gen/ssv/api/endpoint.rs b/anchor/http_api/gen/ssv/api/endpoint.rs new file mode 100644 index 000000000..82f0579e2 --- /dev/null +++ b/anchor/http_api/gen/ssv/api/endpoint.rs @@ -0,0 +1,4306 @@ + +// +// This file is generated from openapi specification. Please do not modify it. +// It should be .gitignored +// +#![allow(warnings)] +#![allow(clippy::all)] + +use async_trait::async_trait; +use axum::{body::Body, http::{HeaderValue, Response, StatusCode}, response::IntoResponse, Json, http}; +use garde::Validate; +use serde::{ + de::{self, IntoDeserializer}, + Deserialize, +}; +use serde_qs::Error; +use std::fmt; +use axum::extract::FromRequestParts; +use axum::http::request::Parts; + + + + + +#[derive(Debug)] +pub struct FailedToDeserializeQuery(Error); + +impl IntoResponse for FailedToDeserializeQuery { + fn into_response(self) -> axum::response::Response { + (http::StatusCode::BAD_REQUEST, self.0.to_string()).into_response() + } +} + +/// GET /api/v4/{network}/accounts +/// path parameters +#[derive(Validate, Deserialize)] +pub struct AccountV4ControllerListPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/accounts +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct AccountV4ControllerListQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=100)))] + #[serde(rename = "perPage")] + pub per_page: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum AccountV4ControllerListResponse { + Status200,Status404,Status500, +} + +impl IntoResponse for AccountV4ControllerListResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: AccountV4ControllerListResponse) -> Response { + match response { + + + AccountV4ControllerListResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + AccountV4ControllerListResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + AccountV4ControllerListResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/accounts/{ownerAddress} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct AccountV4ControllerByIdPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "ownerAddress")] + pub owner_address: AccountV4ControllerByIdOwnerAddressPathVariant, + +} + + + + + + + + + + + + + + + + + +pub enum AccountV4ControllerByIdResponse { + Status200,Status500, +} + +impl IntoResponse for AccountV4ControllerByIdResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: AccountV4ControllerByIdResponse) -> Response { + match response { + + + AccountV4ControllerByIdResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + AccountV4ControllerByIdResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/accounts/counts/{ownerAddress} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ApiV4AccountsCountsGetPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(skip)] + #[serde(rename = "ownerAddress")] + pub owner_address: String, + +} + + + + + + + + + + + + + + + + + + + + + + + +pub enum ApiV4AccountsCountsGetResponse { + Status200,Status400,Status500, +} + +impl IntoResponse for ApiV4AccountsCountsGetResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ApiV4AccountsCountsGetResponse) -> Response { + match response { + + + ApiV4AccountsCountsGetResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ApiV4AccountsCountsGetResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + ApiV4AccountsCountsGetResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/clusters/count +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ClusterV4ControllerCountPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + +pub enum ClusterV4ControllerCountResponse { + Status200,Status500, +} + +impl IntoResponse for ClusterV4ControllerCountResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ClusterV4ControllerCountResponse) -> Response { + match response { + + + ClusterV4ControllerCountResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ClusterV4ControllerCountResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/clusters +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ClusterV4ControllerListPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/clusters +/// query parameters +#[derive(Validate, Deserialize)] +pub struct ClusterV4ControllerListQuery{ + #[garde(range(min=1))] + #[serde(rename = "from")] + pub from: f64, + + #[garde(range(min=1))] + #[serde(rename = "limit")] + pub limit: f64, + + #[garde(dive)] + #[serde(rename = "operatorDetails")] + pub operator_details: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum ClusterV4ControllerListResponse { + Status200,Status404,Status500, +} + +impl IntoResponse for ClusterV4ControllerListResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ClusterV4ControllerListResponse) -> Response { + match response { + + + ClusterV4ControllerListResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ClusterV4ControllerListResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + ClusterV4ControllerListResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/clusters/updates +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ClusterV4ControllerUpdatesPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/clusters/updates +/// query parameters +#[derive(Validate, Deserialize)] +pub struct ClusterV4ControllerUpdatesQuery{ + #[garde(range(min=1))] + #[serde(rename = "fromBlock")] + pub from_block: f64, + +} + + + + + + + + + + + + + + + + + + +pub enum ClusterV4ControllerUpdatesResponse { + Status200,Status500, +} + +impl IntoResponse for ClusterV4ControllerUpdatesResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ClusterV4ControllerUpdatesResponse) -> Response { + match response { + + + ClusterV4ControllerUpdatesResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ClusterV4ControllerUpdatesResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/clusters/{id} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ClusterV4ControllerByIdPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "id")] + pub id: ClusterV4ControllerByIdIdPathVariant, + +} + + + + +/// GET /api/v4/{network}/clusters/{id} +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct ClusterV4ControllerByIdQuery{ + #[garde(dive)] + #[serde(rename = "operatorDetails")] + pub operator_details: Option, + +} + + + + + + + + + + + + + + + + + + +pub enum ClusterV4ControllerByIdResponse { + Status200,Status500, +} + +impl IntoResponse for ClusterV4ControllerByIdResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ClusterV4ControllerByIdResponse) -> Response { + match response { + + + ClusterV4ControllerByIdResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ClusterV4ControllerByIdResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/clusters/owner/{owner}/operators/{operators} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ClusterV4ControllerByOwnerAndOperatorsPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "owner")] + pub owner: ClusterV4ControllerByOwnerAndOperatorsOwnerPathVariant, + #[garde(dive)] + #[serde(rename = "operators")] + pub operators: ClusterV4ControllerByOwnerAndOperatorsOperatorsPathVariant, + +} + + + + +/// GET /api/v4/{network}/clusters/owner/{owner}/operators/{operators} +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct ClusterV4ControllerByOwnerAndOperatorsQuery{ + #[garde(dive)] + #[serde(rename = "operatorDetails")] + pub operator_details: Option, + +} + + + + + + + + + + + + + + + + + + +pub enum ClusterV4ControllerByOwnerAndOperatorsResponse { + Status200,Status500, +} + +impl IntoResponse for ClusterV4ControllerByOwnerAndOperatorsResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ClusterV4ControllerByOwnerAndOperatorsResponse) -> Response { + match response { + + + ClusterV4ControllerByOwnerAndOperatorsResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ClusterV4ControllerByOwnerAndOperatorsResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/clusters/owner/{owner} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ClusterV4ControllerByOwnerPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "owner")] + pub owner: ClusterV4ControllerByOwnerOwnerPathVariant, + +} + + + + +/// GET /api/v4/{network}/clusters/owner/{owner} +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct ClusterV4ControllerByOwnerQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=100)))] + #[serde(rename = "perPage")] + pub per_page: Option, + + #[garde(skip)] + #[serde(rename = "ordering")] + pub ordering: Option, + + #[garde(dive)] + #[serde(rename = "operatorDetails")] + pub operator_details: Option, + +} + + + + + + + + + + + + + + + + + + +pub enum ClusterV4ControllerByOwnerResponse { + Status200,Status500, +} + +impl IntoResponse for ClusterV4ControllerByOwnerResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ClusterV4ControllerByOwnerResponse) -> Response { + match response { + + + ClusterV4ControllerByOwnerResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ClusterV4ControllerByOwnerResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/clusters/hash/{clusterHash} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ClusterV4ControllerValidatorsPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "clusterHash")] + pub cluster_hash: ClusterV4ControllerValidatorsClusterHashPathVariant, + +} + + + + +/// GET /api/v4/{network}/clusters/hash/{clusterHash} +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct ClusterV4ControllerValidatorsQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=100)))] + #[serde(rename = "perPage")] + pub per_page: Option, + +} + + + + + + + + + + + + + + + + + + +pub enum ClusterV4ControllerValidatorsResponse { + Status200,Status500, +} + +impl IntoResponse for ClusterV4ControllerValidatorsResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ClusterV4ControllerValidatorsResponse) -> Response { + match response { + + + ClusterV4ControllerValidatorsResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ClusterV4ControllerValidatorsResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/duties/{validator} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct DutiesV4ControllerDutiesPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "validator")] + pub validator: DutiesV4ControllerDutiesValidatorPathVariant, + +} + + + + +/// GET /api/v4/{network}/duties/{validator} +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct DutiesV4ControllerDutiesQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=100)))] + #[serde(rename = "perPage")] + pub per_page: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum DutiesV4ControllerDutiesResponse { + Status200,Status400,Status404,Status500, +} + +impl IntoResponse for DutiesV4ControllerDutiesResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: DutiesV4ControllerDutiesResponse) -> Response { + match response { + + + DutiesV4ControllerDutiesResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + DutiesV4ControllerDutiesResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + DutiesV4ControllerDutiesResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + DutiesV4ControllerDutiesResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/events/{txHash} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ApiV4EventsGetPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(skip)] + #[serde(rename = "txHash")] + pub tx_hash: String, + +} + + + + + + + + + + + + + + + + + +pub enum ApiV4EventsGetResponse { + Status200,Status500, +} + +impl IntoResponse for ApiV4EventsGetResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ApiV4EventsGetResponse) -> Response { + match response { + + + ApiV4EventsGetResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ApiV4EventsGetResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/faucet +/// path parameters +#[derive(Validate, Deserialize)] +pub struct FaucetControllerGetTransactionsPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + +pub enum FaucetControllerGetTransactionsResponse { + Status200,Status500, +} + +impl IntoResponse for FaucetControllerGetTransactionsResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: FaucetControllerGetTransactionsResponse) -> Response { + match response { + + + FaucetControllerGetTransactionsResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + FaucetControllerGetTransactionsResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// POST /api/v4/{network}/faucet +/// path parameters +#[derive(Validate, Deserialize)] +pub struct FaucetControllerSetTransactionPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum FaucetControllerSetTransactionResponse { + Status200,Status400,Status406,Status500, +} + +impl IntoResponse for FaucetControllerSetTransactionResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: FaucetControllerSetTransactionResponse) -> Response { + match response { + + + FaucetControllerSetTransactionResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + FaucetControllerSetTransactionResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + FaucetControllerSetTransactionResponse::Status406 => StatusCode::from_u16(406).unwrap().into_response(), + + + FaucetControllerSetTransactionResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/faucet/config +/// path parameters +#[derive(Validate, Deserialize)] +pub struct FaucetControllerGetFaucetConfigPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + +pub enum FaucetControllerGetFaucetConfigResponse { + Status200,Status500, +} + +impl IntoResponse for FaucetControllerGetFaucetConfigResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: FaucetControllerGetFaucetConfigResponse) -> Response { + match response { + + + FaucetControllerGetFaucetConfigResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + FaucetControllerGetFaucetConfigResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + +/// GET /api/finance/currency/convert/{symbol}/{quote} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct FinanceControllerCurrencyConvertPath{#[garde(dive)] + #[serde(rename = "symbol")] + pub symbol: FinanceControllerCurrencyConvertSymbolPathVariant, + #[garde(dive)] + #[serde(rename = "quote")] + pub quote: FinanceControllerCurrencyConvertQuotePathVariant, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum FinanceControllerCurrencyConvertResponse { + Status200(serde_json::Value),Status404(serde_json::Value),Status429(serde_json::Value),Status500, +} + +impl IntoResponse for FinanceControllerCurrencyConvertResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: FinanceControllerCurrencyConvertResponse) -> Response { + match response { + + + FinanceControllerCurrencyConvertResponse::Status200(model) => + + +(StatusCode::from_u16(200).unwrap(), Json(model)).into_response() + + , + + + FinanceControllerCurrencyConvertResponse::Status404(model) => + + +(StatusCode::from_u16(404).unwrap(), Json(model)).into_response() + + , + + + FinanceControllerCurrencyConvertResponse::Status429(model) => + + +(StatusCode::from_u16(429).unwrap(), Json(model)).into_response() + + , + + + FinanceControllerCurrencyConvertResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/operators/graph +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerGraphPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/operators/graph +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct OperatorsV4ControllerGraphQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=10000)))] + #[serde(rename = "perPage")] + pub per_page: Option, + + #[garde(skip)] + #[serde(rename = "randomize")] + pub randomize: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerGraphResponse { + Status200,Status404,Status500, +} + +impl IntoResponse for OperatorsV4ControllerGraphResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerGraphResponse) -> Response { + match response { + + + OperatorsV4ControllerGraphResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerGraphResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + OperatorsV4ControllerGraphResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/health +/// path parameters +#[derive(Validate, Deserialize)] +pub struct HealthV4ControllerHealthPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + +pub enum HealthV4ControllerHealthResponse { + Status200,Status500, +} + +impl IntoResponse for HealthV4ControllerHealthResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: HealthV4ControllerHealthResponse) -> Response { + match response { + + + HealthV4ControllerHealthResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + HealthV4ControllerHealthResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/incentivization/merkle-tree +/// path parameters +#[derive(Validate, Deserialize)] +pub struct IncentivizationV4ControllerMigrationOperatorsDistributionPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + +pub enum IncentivizationV4ControllerMigrationOperatorsDistributionResponse { + Status200, +} + +impl IntoResponse for IncentivizationV4ControllerMigrationOperatorsDistributionResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: IncentivizationV4ControllerMigrationOperatorsDistributionResponse) -> Response { + match response { + + + IncentivizationV4ControllerMigrationOperatorsDistributionResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + } + } +} + + + + + + + + + + +/// GET /api/v4/{network}/operators/graph +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerGraphPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/operators/graph +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct OperatorsV4ControllerGraphQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=10000)))] + #[serde(rename = "perPage")] + pub per_page: Option, + + #[garde(skip)] + #[serde(rename = "randomize")] + pub randomize: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerGraphResponse { + Status200,Status404,Status500, +} + +impl IntoResponse for OperatorsV4ControllerGraphResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerGraphResponse) -> Response { + match response { + + + OperatorsV4ControllerGraphResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerGraphResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + OperatorsV4ControllerGraphResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/operators/owned_by/{ownerAddress} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerOwnedByPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "ownerAddress")] + pub owner_address: OperatorsV4ControllerOwnedByOwnerAddressPathVariant, + +} + + + + +/// GET /api/v4/{network}/operators/owned_by/{ownerAddress} +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct OperatorsV4ControllerOwnedByQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=100)))] + #[serde(rename = "perPage")] + pub per_page: Option, + + #[garde(skip)] + #[serde(rename = "ordering")] + pub ordering: Option, + +} + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerOwnedByResponse { + Status200,Status500, +} + +impl IntoResponse for OperatorsV4ControllerOwnedByResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerOwnedByResponse) -> Response { + match response { + + + OperatorsV4ControllerOwnedByResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerOwnedByResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/operators/incentivized/{operator} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerIncentivizedPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "operator")] + pub operator: OperatorsV4ControllerIncentivizedOperatorPathVariant, + +} + + + + +/// GET /api/v4/{network}/operators/incentivized/{operator} +/// query parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerIncentivizedQuery{ + #[garde(range(min=1))] + #[serde(rename = "epochFrom")] + pub epoch_from: f64, + + #[garde(range(min=1))] + #[serde(rename = "epochsPerRound")] + pub epochs_per_round: f64, + + #[garde(inner(range(min=1,max=5)))] + #[serde(rename = "rounds")] + pub rounds: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerIncentivizedResponse { + Status200,Status400,Status404,Status500, +} + +impl IntoResponse for OperatorsV4ControllerIncentivizedResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerIncentivizedResponse) -> Response { + match response { + + + OperatorsV4ControllerIncentivizedResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerIncentivizedResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + OperatorsV4ControllerIncentivizedResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + OperatorsV4ControllerIncentivizedResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/operators/{operator} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerGetOperatorPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "operator")] + pub operator: OperatorsV4ControllerGetOperatorOperatorPathVariant, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerGetOperatorResponse { + Status200,Status400,Status404,Status500, +} + +impl IntoResponse for OperatorsV4ControllerGetOperatorResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerGetOperatorResponse) -> Response { + match response { + + + OperatorsV4ControllerGetOperatorResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerGetOperatorResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + OperatorsV4ControllerGetOperatorResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + OperatorsV4ControllerGetOperatorResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// POST /api/v4/{network}/operators/dkg_health_check +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerGetDkgHealthCheckPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerGetDkgHealthCheckResponse { + Status200,Status201,Status500, +} + +impl IntoResponse for OperatorsV4ControllerGetDkgHealthCheckResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerGetDkgHealthCheckResponse) -> Response { + match response { + + + OperatorsV4ControllerGetDkgHealthCheckResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerGetDkgHealthCheckResponse::Status201 => StatusCode::from_u16(201).unwrap().into_response(), + + + OperatorsV4ControllerGetDkgHealthCheckResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/operators/public_key/{public_key} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerGetByPublicKeyPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "public_key")] + pub public_key: OperatorsV4ControllerGetByPublicKeyPublicKeyPathVariant, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerGetByPublicKeyResponse { + Status200,Status400,Status404,Status500, +} + +impl IntoResponse for OperatorsV4ControllerGetByPublicKeyResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerGetByPublicKeyResponse) -> Response { + match response { + + + OperatorsV4ControllerGetByPublicKeyResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerGetByPublicKeyResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + OperatorsV4ControllerGetByPublicKeyResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + OperatorsV4ControllerGetByPublicKeyResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/operators +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerOperatorsPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/operators +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct OperatorsV4ControllerOperatorsQuery{ + #[garde(skip)] + #[serde(rename = "type")] + pub type_: Option, + + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=5000)))] + #[serde(rename = "perPage")] + pub per_page: Option, + + #[garde(skip)] + #[serde(rename = "ordering")] + pub ordering: Option, + + #[garde(skip)] + #[serde(rename = "search")] + pub search: Option, + + #[garde(skip)] + #[serde(rename = "has_dkg_address")] + pub has_dkg_address: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerOperatorsResponse { + Status200,Status404,Status500, +} + +impl IntoResponse for OperatorsV4ControllerOperatorsResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerOperatorsResponse) -> Response { + match response { + + + OperatorsV4ControllerOperatorsResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerOperatorsResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + OperatorsV4ControllerOperatorsResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// POST /api/v4/{network}/operators +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerGetByIdsPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerGetByIdsResponse { + Status200,Status500, +} + +impl IntoResponse for OperatorsV4ControllerGetByIdsResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerGetByIdsResponse) -> Response { + match response { + + + OperatorsV4ControllerGetByIdsResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerGetByIdsResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// PUT /api/v4/{network}/operators/{operator}/metadata +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerUpdateMetadataPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(skip)] + #[serde(rename = "operator")] + pub operator: String, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerUpdateMetadataResponse { + Status200,Status401,Status404,Status500, +} + +impl IntoResponse for OperatorsV4ControllerUpdateMetadataResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerUpdateMetadataResponse) -> Response { + match response { + + + OperatorsV4ControllerUpdateMetadataResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerUpdateMetadataResponse::Status401 => StatusCode::from_u16(401).unwrap().into_response(), + + + OperatorsV4ControllerUpdateMetadataResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + OperatorsV4ControllerUpdateMetadataResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/operators/nodes/{layer} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerNodesPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "layer")] + pub layer: OperatorsV4ControllerNodesLayerPathVariant, + +} + + + + + + + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerNodesResponse { + Status200,Status400,Status500, +} + +impl IntoResponse for OperatorsV4ControllerNodesResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerNodesResponse) -> Response { + match response { + + + OperatorsV4ControllerNodesResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerNodesResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + OperatorsV4ControllerNodesResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/operators/locations +/// path parameters +#[derive(Validate, Deserialize)] +pub struct OperatorsV4ControllerLocationsPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + +pub enum OperatorsV4ControllerLocationsResponse { + Status200,Status500, +} + +impl IntoResponse for OperatorsV4ControllerLocationsResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: OperatorsV4ControllerLocationsResponse) -> Response { + match response { + + + OperatorsV4ControllerLocationsResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + OperatorsV4ControllerLocationsResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/search +/// path parameters +#[derive(Validate, Deserialize)] +pub struct SearchV4ControllerSearchPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/search +/// query parameters +#[derive(Validate, Deserialize)] +pub struct SearchV4ControllerSearchQuery{ + #[garde(skip)] + #[serde(rename = "search")] + pub search: String, + + #[garde(skip)] + #[serde(rename = "searchFor")] + pub search_for: Option, + + #[garde(inner(range(min=0)))] + #[serde(rename = "operatorsLimit")] + pub operators_limit: Option, + + #[garde(inner(range(min=0)))] + #[serde(rename = "validatorsLimit")] + pub validators_limit: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum SearchV4ControllerSearchResponse { + Status200,Status400,Status500, +} + +impl IntoResponse for SearchV4ControllerSearchResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: SearchV4ControllerSearchResponse) -> Response { + match response { + + + SearchV4ControllerSearchResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + SearchV4ControllerSearchResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + SearchV4ControllerSearchResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/validators/countActiveValidators +/// path parameters +#[derive(Validate, Deserialize)] +pub struct CountActiveValidatorsInNetworkPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + +pub enum CountActiveValidatorsInNetworkResponse { + Status200,Status500, +} + +impl IntoResponse for CountActiveValidatorsInNetworkResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: CountActiveValidatorsInNetworkResponse) -> Response { + match response { + + + CountActiveValidatorsInNetworkResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + CountActiveValidatorsInNetworkResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/validators/owned_by/{ownerAddress}/cost +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ValidatorsV4ControllerCostPath{#[garde(dive)] + #[serde(rename = "ownerAddress")] + pub owner_address: ValidatorsV4ControllerCostOwnerAddressPathVariant, + #[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + + + + + + + +pub enum ValidatorsV4ControllerCostResponse { + Status200,Status400,Status500, +} + +impl IntoResponse for ValidatorsV4ControllerCostResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ValidatorsV4ControllerCostResponse) -> Response { + match response { + + + ValidatorsV4ControllerCostResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ValidatorsV4ControllerCostResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + ValidatorsV4ControllerCostResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/validators/in_operator/{operator} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ValidatorsV4ControllerInOperatorPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "operator")] + pub operator: ValidatorsV4ControllerInOperatorOperatorPathVariant, + +} + + + + +/// GET /api/v4/{network}/validators/in_operator/{operator} +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct ValidatorsV4ControllerInOperatorQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=100)))] + #[serde(rename = "perPage")] + pub per_page: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum ValidatorsV4ControllerInOperatorResponse { + Status200,Status404,Status500, +} + +impl IntoResponse for ValidatorsV4ControllerInOperatorResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ValidatorsV4ControllerInOperatorResponse) -> Response { + match response { + + + ValidatorsV4ControllerInOperatorResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ValidatorsV4ControllerInOperatorResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + ValidatorsV4ControllerInOperatorResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/validators/incentivized/{validator} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ValidatorsV4ControllerIncentivizedPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "validator")] + pub validator: ValidatorsV4ControllerIncentivizedValidatorPathVariant, + +} + + + + +/// GET /api/v4/{network}/validators/incentivized/{validator} +/// query parameters +#[derive(Validate, Deserialize)] +pub struct ValidatorsV4ControllerIncentivizedQuery{ + #[garde(range(min=1))] + #[serde(rename = "epochFrom")] + pub epoch_from: f64, + + #[garde(range(min=1))] + #[serde(rename = "epochsPerRound")] + pub epochs_per_round: f64, + + #[garde(inner(range(min=1,max=5)))] + #[serde(rename = "rounds")] + pub rounds: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum ValidatorsV4ControllerIncentivizedResponse { + Status200,Status400,Status404,Status500, +} + +impl IntoResponse for ValidatorsV4ControllerIncentivizedResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ValidatorsV4ControllerIncentivizedResponse) -> Response { + match response { + + + ValidatorsV4ControllerIncentivizedResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ValidatorsV4ControllerIncentivizedResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + ValidatorsV4ControllerIncentivizedResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + ValidatorsV4ControllerIncentivizedResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/validators/{validator} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ValidatorsV4ControllerValidatorPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "validator")] + pub validator: ValidatorsV4ControllerValidatorValidatorPathVariant, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum ValidatorsV4ControllerValidatorResponse { + Status200,Status400,Status404,Status500, +} + +impl IntoResponse for ValidatorsV4ControllerValidatorResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ValidatorsV4ControllerValidatorResponse) -> Response { + match response { + + + ValidatorsV4ControllerValidatorResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ValidatorsV4ControllerValidatorResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + ValidatorsV4ControllerValidatorResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + ValidatorsV4ControllerValidatorResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/validators/isRegisteredValidator/{validator} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ValidatorsV4ControllerIsRegisteredValidatorPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "validator")] + pub validator: ValidatorsV4ControllerIsRegisteredValidatorValidatorPathVariant, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum ValidatorsV4ControllerIsRegisteredValidatorResponse { + Status200,Status400,Status404,Status500, +} + +impl IntoResponse for ValidatorsV4ControllerIsRegisteredValidatorResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ValidatorsV4ControllerIsRegisteredValidatorResponse) -> Response { + match response { + + + ValidatorsV4ControllerIsRegisteredValidatorResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ValidatorsV4ControllerIsRegisteredValidatorResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + ValidatorsV4ControllerIsRegisteredValidatorResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + ValidatorsV4ControllerIsRegisteredValidatorResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// POST /api/v4/{network}/validators/registeredByPublicKeys +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ApiV4ValidatorRegisteredByPublicKeyCreatePath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + + + + + + + +pub enum ApiV4ValidatorRegisteredByPublicKeyCreateResponse { + Status200,Status400,Status500, +} + +impl IntoResponse for ApiV4ValidatorRegisteredByPublicKeyCreateResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ApiV4ValidatorRegisteredByPublicKeyCreateResponse) -> Response { + match response { + + + ApiV4ValidatorRegisteredByPublicKeyCreateResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ApiV4ValidatorRegisteredByPublicKeyCreateResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + ApiV4ValidatorRegisteredByPublicKeyCreateResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/validators +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ValidatorsV4ControllerValidatorsPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/validators +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct ValidatorsV4ControllerValidatorsQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "lastId")] + pub last_id: Option, + + #[garde(skip)] + #[serde(rename = "pageDirection")] + pub page_direction: Option, + + #[garde(inner(range(min=1,max=1000)))] + #[serde(rename = "perPage")] + pub per_page: Option, + + #[garde(skip)] + #[serde(rename = "ordering")] + pub ordering: Option, + + #[garde(skip)] + #[serde(rename = "ownerAddress")] + pub owner_address: Option, + + #[garde(skip)] + #[serde(rename = "search")] + pub search: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum ValidatorsV4ControllerValidatorsResponse { + Status200,Status404,Status500, +} + +impl IntoResponse for ValidatorsV4ControllerValidatorsResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ValidatorsV4ControllerValidatorsResponse) -> Response { + match response { + + + ValidatorsV4ControllerValidatorsResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ValidatorsV4ControllerValidatorsResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + ValidatorsV4ControllerValidatorsResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/validators/duty_counts/{from_epoch}/{to_epoch} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ValidatorsV4ControllerDutyCountsPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "from_epoch")] + pub from_epoch: ValidatorsV4ControllerDutyCountsFromEpochPathVariant, + #[garde(dive)] + #[serde(rename = "to_epoch")] + pub to_epoch: ValidatorsV4ControllerDutyCountsToEpochPathVariant, + +} + + + + + + + + + + + + + + + + + + + + + + + +pub enum ValidatorsV4ControllerDutyCountsResponse { + Status200,Status404,Status500, +} + +impl IntoResponse for ValidatorsV4ControllerDutyCountsResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ValidatorsV4ControllerDutyCountsResponse) -> Response { + match response { + + + ValidatorsV4ControllerDutyCountsResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ValidatorsV4ControllerDutyCountsResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + ValidatorsV4ControllerDutyCountsResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/validators/validatorsByClusterHash/{clusterHash} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ApiV4ValidatorsValidatorsByClusterHashGetPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(skip)] + #[serde(rename = "clusterHash")] + pub cluster_hash: String, + +} + + + + + + + + + + + + + + + + + + + + + + + +pub enum ApiV4ValidatorsValidatorsByClusterHashGetResponse { + Status200,Status400,Status500, +} + +impl IntoResponse for ApiV4ValidatorsValidatorsByClusterHashGetResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ApiV4ValidatorsValidatorsByClusterHashGetResponse) -> Response { + match response { + + + ApiV4ValidatorsValidatorsByClusterHashGetResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ApiV4ValidatorsValidatorsByClusterHashGetResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + ApiV4ValidatorsValidatorsByClusterHashGetResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// POST /api/v4/{network}/validators/validatorsWithdrawCredentials +/// path parameters +#[derive(Validate, Deserialize)] +pub struct ApiV4ValidatorValidatorsWithdrawCredentialCreatePath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + + + + + + + +pub enum ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse { + Status200,Status400,Status500, +} + +impl IntoResponse for ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse) -> Response { + match response { + + + ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/accounts +/// path parameters +#[derive(Validate, Deserialize)] +pub struct AccountV4ControllerListPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/accounts +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct AccountV4ControllerListQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=100)))] + #[serde(rename = "perPage")] + pub per_page: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum AccountV4ControllerListResponse { + Status200,Status404,Status500, +} + +impl IntoResponse for AccountV4ControllerListResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: AccountV4ControllerListResponse) -> Response { + match response { + + + AccountV4ControllerListResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + AccountV4ControllerListResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + AccountV4ControllerListResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/accounts/{ownerAddress} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct AccountV4ControllerByIdPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "ownerAddress")] + pub owner_address: AccountV4ControllerByIdOwnerAddressPathVariant, + +} + + + + + + + + + + + + + + + + + +pub enum AccountV4ControllerByIdResponse { + Status200,Status500, +} + +impl IntoResponse for AccountV4ControllerByIdResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: AccountV4ControllerByIdResponse) -> Response { + match response { + + + AccountV4ControllerByIdResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + AccountV4ControllerByIdResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/duties/{validator} +/// path parameters +#[derive(Validate, Deserialize)] +pub struct DutiesV4ControllerDutiesPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + #[garde(dive)] + #[serde(rename = "validator")] + pub validator: DutiesV4ControllerDutiesValidatorPathVariant, + +} + + + + +/// GET /api/v4/{network}/duties/{validator} +/// query parameters +#[derive(Validate, Deserialize,Default)] +pub struct DutiesV4ControllerDutiesQuery{ + #[garde(inner(range(min=1)))] + #[serde(rename = "page")] + pub page: Option, + + #[garde(inner(range(min=1,max=100)))] + #[serde(rename = "perPage")] + pub per_page: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +pub enum DutiesV4ControllerDutiesResponse { + Status200,Status400,Status404,Status500, +} + +impl IntoResponse for DutiesV4ControllerDutiesResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: DutiesV4ControllerDutiesResponse) -> Response { + match response { + + + DutiesV4ControllerDutiesResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + DutiesV4ControllerDutiesResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + DutiesV4ControllerDutiesResponse::Status404 => StatusCode::from_u16(404).unwrap().into_response(), + + + DutiesV4ControllerDutiesResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/health +/// path parameters +#[derive(Validate, Deserialize)] +pub struct HealthV4ControllerHealthPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + + + + + + + +pub enum HealthV4ControllerHealthResponse { + Status200,Status500, +} + +impl IntoResponse for HealthV4ControllerHealthResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: HealthV4ControllerHealthResponse) -> Response { + match response { + + + HealthV4ControllerHealthResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + HealthV4ControllerHealthResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + +/// GET /api/v4/{network}/incentivization/merkle-tree +/// path parameters +#[derive(Validate, Deserialize)] +pub struct IncentivizationV4ControllerMigrationOperatorsDistributionPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + + + + + + + + +pub enum IncentivizationV4ControllerMigrationOperatorsDistributionResponse { + Status200, +} + +impl IntoResponse for IncentivizationV4ControllerMigrationOperatorsDistributionResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: IncentivizationV4ControllerMigrationOperatorsDistributionResponse) -> Response { + match response { + + + IncentivizationV4ControllerMigrationOperatorsDistributionResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + } + } +} + + + + + + + + + +/// GET /api/v4/{network}/search +/// path parameters +#[derive(Validate, Deserialize)] +pub struct SearchV4ControllerSearchPath{#[garde(skip)] + #[serde(rename = "network")] + pub network: String, + +} + + + + +/// GET /api/v4/{network}/search +/// query parameters +#[derive(Validate, Deserialize)] +pub struct SearchV4ControllerSearchQuery{ + #[garde(skip)] + #[serde(rename = "search")] + pub search: String, + + #[garde(skip)] + #[serde(rename = "searchFor")] + pub search_for: Option, + + #[garde(inner(range(min=0)))] + #[serde(rename = "operatorsLimit")] + pub operators_limit: Option, + + #[garde(inner(range(min=0)))] + #[serde(rename = "validatorsLimit")] + pub validators_limit: Option, + +} + + + + + + + + + + + + + + + + + + + + + + + + +pub enum SearchV4ControllerSearchResponse { + Status200,Status400,Status500, +} + +impl IntoResponse for SearchV4ControllerSearchResponse { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From for Response { + fn from(response: SearchV4ControllerSearchResponse) -> Response { + match response { + + + SearchV4ControllerSearchResponse::Status200 => StatusCode::from_u16(200).unwrap().into_response(), + + + SearchV4ControllerSearchResponse::Status400 => StatusCode::from_u16(400).unwrap().into_response(), + + + SearchV4ControllerSearchResponse::Status500 => StatusCode::from_u16(500).unwrap().into_response(), + + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + +/// all convertable Result are acceptable +macro_rules! impl_from_result { + ($t:ident) => { + impl From> for $t + where + O: Into<$t>, + E: Into<$t>, + { + fn from(res: Result) -> Self { + match res { + Ok(r) => r.into(), + Err(e) => e.into(), + } + } + } + }; +} + + +impl_from_result!(AccountV4ControllerListResponse); +impl_from_result!(AccountV4ControllerByIdResponse); +impl_from_result!(ApiV4AccountsCountsGetResponse); +impl_from_result!(ClusterV4ControllerCountResponse); +impl_from_result!(ClusterV4ControllerListResponse); +impl_from_result!(ClusterV4ControllerUpdatesResponse); +impl_from_result!(ClusterV4ControllerByIdResponse); +impl_from_result!(ClusterV4ControllerByOwnerAndOperatorsResponse); +impl_from_result!(ClusterV4ControllerByOwnerResponse); +impl_from_result!(ClusterV4ControllerValidatorsResponse); +impl_from_result!(DutiesV4ControllerDutiesResponse); +impl_from_result!(ApiV4EventsGetResponse); +impl_from_result!(FaucetControllerGetTransactionsResponse); +impl_from_result!(FaucetControllerSetTransactionResponse); +impl_from_result!(FaucetControllerGetFaucetConfigResponse); +impl_from_result!(FinanceControllerCurrencyConvertResponse); +impl_from_result!(OperatorsV4ControllerGraphResponse); +impl_from_result!(HealthV4ControllerHealthResponse); +impl_from_result!(IncentivizationV4ControllerMigrationOperatorsDistributionResponse); +impl_from_result!(OperatorsV4ControllerGraphResponse); +impl_from_result!(OperatorsV4ControllerOwnedByResponse); +impl_from_result!(OperatorsV4ControllerIncentivizedResponse); +impl_from_result!(OperatorsV4ControllerGetOperatorResponse); +impl_from_result!(OperatorsV4ControllerGetDkgHealthCheckResponse); +impl_from_result!(OperatorsV4ControllerGetByPublicKeyResponse); +impl_from_result!(OperatorsV4ControllerOperatorsResponse); +impl_from_result!(OperatorsV4ControllerGetByIdsResponse); +impl_from_result!(OperatorsV4ControllerUpdateMetadataResponse); +impl_from_result!(OperatorsV4ControllerNodesResponse); +impl_from_result!(OperatorsV4ControllerLocationsResponse); +impl_from_result!(SearchV4ControllerSearchResponse); +impl_from_result!(CountActiveValidatorsInNetworkResponse); +impl_from_result!(ValidatorsV4ControllerCostResponse); +impl_from_result!(ValidatorsV4ControllerInOperatorResponse); +impl_from_result!(ValidatorsV4ControllerIncentivizedResponse); +impl_from_result!(ValidatorsV4ControllerValidatorResponse); +impl_from_result!(ValidatorsV4ControllerIsRegisteredValidatorResponse); +impl_from_result!(ApiV4ValidatorRegisteredByPublicKeyCreateResponse); +impl_from_result!(ValidatorsV4ControllerValidatorsResponse); +impl_from_result!(ValidatorsV4ControllerDutyCountsResponse); +impl_from_result!(ApiV4ValidatorsValidatorsByClusterHashGetResponse); +impl_from_result!(ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse); +impl_from_result!(AccountV4ControllerListResponse); +impl_from_result!(AccountV4ControllerByIdResponse); +impl_from_result!(DutiesV4ControllerDutiesResponse); +impl_from_result!(HealthV4ControllerHealthResponse); +impl_from_result!(IncentivizationV4ControllerMigrationOperatorsDistributionResponse); +impl_from_result!(SearchV4ControllerSearchResponse); + +/// custom deserializer for query parameters /users?id=3,4,5 +/// style = form, explode = false according to https://swagger.io/docs/specification/serialization/ +pub fn deserialized_id_list<'de, D, I>(deserializer: D) -> std::result::Result, D::Error> +where + D: de::Deserializer<'de>, + I: de::DeserializeOwned, +{ + struct StringVecVisitor(std::marker::PhantomData); + + impl<'de, I> de::Visitor<'de> for StringVecVisitor + where I: de::DeserializeOwned { + type Value = Vec; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a string containing a list") + } + + fn visit_str(self, v: &str) -> std::result::Result + where + E: de::Error, + { + let mut ids = Vec::new(); + for id in v.split(',') { + let id = I::deserialize(id.into_deserializer())?; + ids.push(id); + } + Ok(ids) + } + } + + deserializer.deserialize_any(StringVecVisitor(std::marker::PhantomData::)) +} + +pub fn deserialized_opt_id_list<'de, D, I>(deserializer: D) -> std::result::Result>, D::Error> +where + D: de::Deserializer<'de>, + I: de::DeserializeOwned, +{ + struct StringVecVisitor(std::marker::PhantomData); + + impl<'de, I> de::Visitor<'de> for StringVecVisitor + where I: de::DeserializeOwned { + type Value = Option>; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a string containing a list") + } + + fn visit_str(self, v: &str) -> std::result::Result + where + E: de::Error, + { + let mut ids = Vec::new(); + for id in v.split(',') { + let id = I::deserialize(id.into_deserializer())?; + ids.push(id); + } + Ok(Some(ids)) + } + + fn visit_none(self) -> std::result::Result + where + E: de::Error, + { + Ok(None) + } + } + + deserializer.deserialize_any(StringVecVisitor(std::marker::PhantomData::)) +} diff --git a/anchor/http_api/gen/ssv/api/mod.rs b/anchor/http_api/gen/ssv/api/mod.rs new file mode 100644 index 000000000..c30a8239a --- /dev/null +++ b/anchor/http_api/gen/ssv/api/mod.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, unused_imports, unused_variables, clippy::all)] + +// +// This file is generated from openapi specification. Please do not modify it. +// It should be .gitignored +// +#![allow(warnings)] +#![allow(clippy::all)] + + +pub mod endpoint; +pub mod model; +pub mod service; \ No newline at end of file diff --git a/anchor/http_api/gen/ssv/api/model.rs b/anchor/http_api/gen/ssv/api/model.rs new file mode 100644 index 000000000..1e7fdf46d --- /dev/null +++ b/anchor/http_api/gen/ssv/api/model.rs @@ -0,0 +1,608 @@ + + +// +// This file is generated from openapi specification. Please do not modify it. +// It should be .gitignored +// +#![allow(warnings)] +#![allow(clippy::all)] + +use serde::{Serialize, Deserialize, Deserializer}; +use std::collections::BTreeMap; +use garde::Validate; +use regex::Regex; +use once_cell::sync::Lazy; + + + + + + +pub static UUID: Lazy = Lazy::new(|| { Regex::new(r"^\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b$").unwrap() }); +pub static FLOAT: Lazy = Lazy::new(|| { Regex::new(r"^[0-9\.]+$").unwrap() }); + + + + +#[derive(Deserialize, Serialize, Debug, Validate, Clone)] +pub struct OperatorMetadataDto {#[garde(skip)] + #[serde(rename = "operatorName", skip_serializing_if = "Option::is_none")] + pub operator_name: Option,#[garde(skip)] + #[serde(rename = "description", skip_serializing_if = "Option::is_none")] + pub description: Option,#[garde(skip)] + #[serde(rename = "location", skip_serializing_if = "Option::is_none")] + pub location: Option,#[garde(skip)] + #[serde(rename = "setupProvider", skip_serializing_if = "Option::is_none")] + pub setup_provider: Option,#[garde(skip)] + #[serde(rename = "eth1NodeClient", skip_serializing_if = "Option::is_none")] + pub eth_1_node_client: Option,#[garde(skip)] + #[serde(rename = "eth2NodeClient", skip_serializing_if = "Option::is_none")] + pub eth_2_node_client: Option,#[garde(skip)] + #[serde(rename = "mevRelays", skip_serializing_if = "Option::is_none")] + pub mev_relays: Option,#[garde(skip)] + #[serde(rename = "websiteUrl", skip_serializing_if = "Option::is_none")] + pub website_url: Option,#[garde(skip)] + #[serde(rename = "twitterUrl", skip_serializing_if = "Option::is_none")] + pub twitter_url: Option,#[garde(skip)] + #[serde(rename = "linkedinUrl", skip_serializing_if = "Option::is_none")] + pub linkedin_url: Option,#[garde(skip)] + #[serde(rename = "dkgAddress", skip_serializing_if = "Option::is_none")] + pub dkg_address: Option,#[garde(skip)] + #[serde(rename = "logo", skip_serializing_if = "Option::is_none")] + pub logo: Option,#[garde(skip)] + #[serde(rename = "signature")] + pub signature: String, +} + +impl OperatorMetadataDto { + pub fn new(operator_name: Option, description: Option, location: Option, setup_provider: Option, eth_1_node_client: Option, eth_2_node_client: Option, mev_relays: Option, website_url: Option, twitter_url: Option, linkedin_url: Option, dkg_address: Option, logo: Option, signature: String, ) -> Self { + Self { + operator_name, + description, + location, + setup_provider, + eth_1_node_client, + eth_2_node_client, + mev_relays, + website_url, + twitter_url, + linkedin_url, + dkg_address, + logo, + signature, + + } + } + + +} + + + +#[derive(Deserialize, Serialize, Debug, Validate, Clone)] +pub struct DkgHealthCheckDto {#[garde(skip)] + #[serde(rename = "dkgAddress")] + pub dkg_address: String, +} + +impl DkgHealthCheckDto { + pub fn new(dkg_address: String, ) -> Self { + Self { + dkg_address, + + } + } + + +} + + + +#[derive(Deserialize, Serialize, Debug, Validate, Clone, Default)] +pub struct ValidatorPublicKeysDtoPublicKeys { +} + +impl ValidatorPublicKeysDtoPublicKeys { + pub fn new() -> Self { + Self { + + } + } + + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum AccountV4ControllerByIdOwnerAddressPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ClusterV4ControllerListOperatorDetailsQueryVariant { + Bool(#[garde(skip)] + bool + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ClusterV4ControllerByIdIdPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ClusterV4ControllerByIdOperatorDetailsQueryVariant { + Bool(#[garde(skip)] + bool + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ClusterV4ControllerByOwnerAndOperatorsOwnerPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ClusterV4ControllerByOwnerAndOperatorsOperatorsPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ClusterV4ControllerByOwnerAndOperatorsOperatorDetailsQueryVariant { + Bool(#[garde(skip)] + bool + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ClusterV4ControllerByOwnerOperatorDetailsQueryVariant { + Bool(#[garde(skip)] + bool + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ClusterV4ControllerByOwnerOwnerPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ClusterV4ControllerValidatorsClusterHashPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum DutiesV4ControllerDutiesValidatorPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Deserialize, Serialize, Debug, Validate, Clone)] +pub struct FaucetControllerSetTransactionRequestBody {#[garde(skip)] + #[serde(rename = "owner_address", skip_serializing_if = "Option::is_none")] + pub owner_address: Option,#[garde(skip)] + #[serde(rename = "networkId", skip_serializing_if = "Option::is_none")] + pub network_id: Option,#[garde(skip)] + #[serde(rename = "version")] + pub version: String, +} + +impl FaucetControllerSetTransactionRequestBody { + pub fn new(owner_address: Option, network_id: Option, version: String, ) -> Self { + Self { + owner_address, + network_id, + version, + + } + } + + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum FinanceControllerCurrencyConvertSymbolPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum FinanceControllerCurrencyConvertQuotePathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Deserialize, Serialize, Debug, Clone, Validate)] +pub enum OperatorsV4ControllerGraphRandomizeQueryVariant { + + #[serde(rename = "true")] + True, + + #[serde(rename = "false")] + False, + , +} + +impl std::string::ToString for OperatorsV4ControllerGraphRandomizeQueryVariant { + fn to_string(&self) -> String { + match self { + Self::True => "true", + Self::False => "false", + Self:: => "", + }.to_string() + } +} + +impl std::str::FromStr for OperatorsV4ControllerGraphRandomizeQueryVariant { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "true" => Ok(Self::True), + "false" => Ok(Self::False), + "" => Ok(Self::), + _ => Err(()) + } + } +} + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum OperatorsV4ControllerOwnedByOwnerAddressPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum OperatorsV4ControllerIncentivizedOperatorPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum OperatorsV4ControllerGetOperatorOperatorPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Deserialize, Serialize, Debug, Validate, Clone)] +pub struct OperatorsV4ControllerGetDkgHealthCheckRequestBody {#[garde(skip)] + #[serde(rename = "dkgAddress")] + pub dkg_address: String, +} + +impl OperatorsV4ControllerGetDkgHealthCheckRequestBody { + pub fn new(dkg_address: String, ) -> Self { + Self { + dkg_address, + + } + } + + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum OperatorsV4ControllerGetByPublicKeyPublicKeyPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Deserialize, Serialize, Debug, Validate, Clone)] +pub struct OperatorsV4ControllerGetByIdsRequestBody {#[garde(skip)] + #[serde(rename = "ids")] + pub ids: Vec, +} + +impl OperatorsV4ControllerGetByIdsRequestBody { + pub fn new(ids: Vec, ) -> Self { + Self { + ids, + + } + } + + +} + + + +#[derive(Deserialize, Serialize, Debug, Validate, Clone)] +pub struct OperatorsV4ControllerUpdateMetadataRequestBody {#[garde(skip)] + #[serde(rename = "operatorName", skip_serializing_if = "Option::is_none")] + pub operator_name: Option,#[garde(skip)] + #[serde(rename = "description", skip_serializing_if = "Option::is_none")] + pub description: Option,#[garde(skip)] + #[serde(rename = "location", skip_serializing_if = "Option::is_none")] + pub location: Option,#[garde(skip)] + #[serde(rename = "setupProvider", skip_serializing_if = "Option::is_none")] + pub setup_provider: Option,#[garde(skip)] + #[serde(rename = "eth1NodeClient", skip_serializing_if = "Option::is_none")] + pub eth_1_node_client: Option,#[garde(skip)] + #[serde(rename = "eth2NodeClient", skip_serializing_if = "Option::is_none")] + pub eth_2_node_client: Option,#[garde(skip)] + #[serde(rename = "mevRelays", skip_serializing_if = "Option::is_none")] + pub mev_relays: Option,#[garde(skip)] + #[serde(rename = "websiteUrl", skip_serializing_if = "Option::is_none")] + pub website_url: Option,#[garde(skip)] + #[serde(rename = "twitterUrl", skip_serializing_if = "Option::is_none")] + pub twitter_url: Option,#[garde(skip)] + #[serde(rename = "linkedinUrl", skip_serializing_if = "Option::is_none")] + pub linkedin_url: Option,#[garde(skip)] + #[serde(rename = "dkgAddress", skip_serializing_if = "Option::is_none")] + pub dkg_address: Option,#[garde(skip)] + #[serde(rename = "logo", skip_serializing_if = "Option::is_none")] + pub logo: Option,#[garde(skip)] + #[serde(rename = "signature")] + pub signature: String, +} + +impl OperatorsV4ControllerUpdateMetadataRequestBody { + pub fn new(operator_name: Option, description: Option, location: Option, setup_provider: Option, eth_1_node_client: Option, eth_2_node_client: Option, mev_relays: Option, website_url: Option, twitter_url: Option, linkedin_url: Option, dkg_address: Option, logo: Option, signature: String, ) -> Self { + Self { + operator_name, + description, + location, + setup_provider, + eth_1_node_client, + eth_2_node_client, + mev_relays, + website_url, + twitter_url, + linkedin_url, + dkg_address, + logo, + signature, + + } + } + + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum OperatorsV4ControllerNodesLayerPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Deserialize, Serialize, Debug, Clone, Validate)] +pub enum SearchV4ControllerSearchSearchForQueryVariant { + + #[serde(rename = "operators")] + Operators, + + #[serde(rename = "validators")] + Validators, + + #[serde(rename = "both")] + Both, + +} + +impl std::string::ToString for SearchV4ControllerSearchSearchForQueryVariant { + fn to_string(&self) -> String { + match self { + Self::Operators => "operators", + Self::Validators => "validators", + Self::Both => "both", + }.to_string() + } +} + +impl std::str::FromStr for SearchV4ControllerSearchSearchForQueryVariant { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "operators" => Ok(Self::Operators), + "validators" => Ok(Self::Validators), + "both" => Ok(Self::Both), + _ => Err(()) + } + } +} + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ValidatorsV4ControllerCostOwnerAddressPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ValidatorsV4ControllerInOperatorOperatorPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ValidatorsV4ControllerIncentivizedValidatorPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ValidatorsV4ControllerValidatorValidatorPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ValidatorsV4ControllerIsRegisteredValidatorValidatorPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ValidatorsV4ControllerDutyCountsFromEpochPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Debug, Clone, Validate, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ValidatorsV4ControllerDutyCountsToEpochPathVariant { + String(#[garde(skip)] + String + ), + +} + + + +#[derive(Deserialize, Serialize, Debug, Validate, Clone)] +pub struct ApiV4ValidatorValidatorsWithdrawCredentialCreateRequestBody {#[garde(skip)] + #[serde(rename = "publicKeys")] + pub public_keys: Vec, +} + +impl ApiV4ValidatorValidatorsWithdrawCredentialCreateRequestBody { + pub fn new(public_keys: Vec, ) -> Self { + Self { + public_keys, + + } + } + + +} + + + + +pub fn optional_nullable<'de, T, D>(deserializer: D) -> Result, D::Error> + where T: Deserialize<'de>, + D: Deserializer<'de> +{ + Deserialize::deserialize(deserializer).map(Some) +} + + diff --git a/anchor/http_api/gen/ssv/api/service.rs b/anchor/http_api/gen/ssv/api/service.rs new file mode 100644 index 000000000..8bd354ea0 --- /dev/null +++ b/anchor/http_api/gen/ssv/api/service.rs @@ -0,0 +1,8934 @@ + +// +// This file is generated from openapi specification. Please do not modify it. +// It should be .gitignored +// +#![allow(warnings)] +#![allow(clippy::all)] + +use axum::{ + body::{Body, HttpBody}, + extract::{FromRequest, FromRequestParts, Request as ERequest}, + handler::{future::IntoServiceFuture, Handler}, + http::Request, + response::{IntoResponse, Response}, + routing::{self, on_service, MethodFilter}, + Router, BoxError, +}; +use futures::{future::LocalBoxFuture, Future}; +use std::{ + convert::{Infallible, TryFrom}, + marker::PhantomData, + pin::Pin, + task::{Context, Poll}, +}; +use tower_service::Service; +macro_rules! all_the_tuples { + ($name:ident) => { + $name!(T1); + $name!(T1, T2); + $name!(T1, T2, T3); + $name!(T1, T2, T3, T4); + $name!(T1, T2, T3, T4, T5); + } +} + +/// Accounts router +pub struct AccountsRouter { + pub(crate) router: Router, +} + +impl AccountsRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/accounts + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::AccountV4ControllerListPath,super::endpoint::AccountV4ControllerListQuery) -> AccountV4ControllerListResponse { + /// todo!(); + /// } + /// let router = AccountsRouter::default().account_v4_controller_list(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::AccountV4ControllerListPath,super::endpoint::AccountV4ControllerListQuery, ...extractors) -> AccountV4ControllerListResponse { + /// todo!(); + /// } + /// let router = AccountsRouter::default().account_v4_controller_list(handler); + /// ``` + pub fn account_v4_controller_list(mut self, handler: H) -> Self + where + H: AccountV4ControllerListHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/accounts", on_service(MethodFilter::GET, AccountV4ControllerListService::new(handler))); + self + } + + /// GET /api/v4/{network}/accounts/{ownerAddress} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::AccountV4ControllerByIdPath) -> AccountV4ControllerByIdResponse { + /// todo!(); + /// } + /// let router = AccountsRouter::default().account_v4_controller_by_id(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::AccountV4ControllerByIdPath, ...extractors) -> AccountV4ControllerByIdResponse { + /// todo!(); + /// } + /// let router = AccountsRouter::default().account_v4_controller_by_id(handler); + /// ``` + pub fn account_v4_controller_by_id(mut self, handler: H) -> Self + where + H: AccountV4ControllerByIdHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/accounts/:ownerAddress", on_service(MethodFilter::GET, AccountV4ControllerByIdService::new(handler))); + self + } + + /// GET /api/v4/{network}/accounts/counts/{ownerAddress} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4AccountsCountsGetPath) -> ApiV4AccountsCountsGetResponse { + /// todo!(); + /// } + /// let router = AccountsRouter::default().api_v4_accounts_counts_get(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4AccountsCountsGetPath, ...extractors) -> ApiV4AccountsCountsGetResponse { + /// todo!(); + /// } + /// let router = AccountsRouter::default().api_v4_accounts_counts_get(handler); + /// ``` + pub fn api_v4_accounts_counts_get(mut self, handler: H) -> Self + where + H: ApiV4AccountsCountsGetHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/accounts/counts/:ownerAddress", on_service(MethodFilter::GET, ApiV4AccountsCountsGetService::new(handler))); + self + } +} + +impl Default for AccountsRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: AccountsRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/accounts handler +pub trait AccountV4ControllerListHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl AccountV4ControllerListHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::AccountV4ControllerListPath,super::endpoint::AccountV4ControllerListQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::AccountV4ControllerListResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! account_v4_controller_list_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl AccountV4ControllerListHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::AccountV4ControllerListPath,super::endpoint::AccountV4ControllerListQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::AccountV4ControllerListResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(account_v4_controller_list_handler); + +/// GET /api/v4/{network}/accounts service +struct AccountV4ControllerListService +where + H: AccountV4ControllerListHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for AccountV4ControllerListService +where + H: AccountV4ControllerListHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl AccountV4ControllerListService +where + H: AccountV4ControllerListHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for AccountV4ControllerListService +where + H: AccountV4ControllerListHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( AccountV4ControllerListHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/accounts/{ownerAddress} handler +pub trait AccountV4ControllerByIdHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl AccountV4ControllerByIdHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::AccountV4ControllerByIdPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::AccountV4ControllerByIdResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! account_v4_controller_by_id_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl AccountV4ControllerByIdHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::AccountV4ControllerByIdPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::AccountV4ControllerByIdResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(account_v4_controller_by_id_handler); + +/// GET /api/v4/{network}/accounts/{ownerAddress} service +struct AccountV4ControllerByIdService +where + H: AccountV4ControllerByIdHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for AccountV4ControllerByIdService +where + H: AccountV4ControllerByIdHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl AccountV4ControllerByIdService +where + H: AccountV4ControllerByIdHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for AccountV4ControllerByIdService +where + H: AccountV4ControllerByIdHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( AccountV4ControllerByIdHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/accounts/counts/{ownerAddress} handler +pub trait ApiV4AccountsCountsGetHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ApiV4AccountsCountsGetHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ApiV4AccountsCountsGetPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::ApiV4AccountsCountsGetResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! api_v4_accounts_counts_get_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ApiV4AccountsCountsGetHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ApiV4AccountsCountsGetPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::ApiV4AccountsCountsGetResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(api_v4_accounts_counts_get_handler); + +/// GET /api/v4/{network}/accounts/counts/{ownerAddress} service +struct ApiV4AccountsCountsGetService +where + H: ApiV4AccountsCountsGetHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ApiV4AccountsCountsGetService +where + H: ApiV4AccountsCountsGetHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ApiV4AccountsCountsGetService +where + H: ApiV4AccountsCountsGetHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ApiV4AccountsCountsGetService +where + H: ApiV4AccountsCountsGetHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ApiV4AccountsCountsGetHandler::call(handler, req, state).await) + }) + } +} + + + +/// Clusters router +pub struct ClustersRouter { + pub(crate) router: Router, +} + +impl ClustersRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/clusters/count + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerCountPath) -> ClusterV4ControllerCountResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_count(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerCountPath, ...extractors) -> ClusterV4ControllerCountResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_count(handler); + /// ``` + pub fn cluster_v4_controller_count(mut self, handler: H) -> Self + where + H: ClusterV4ControllerCountHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/clusters/count", on_service(MethodFilter::GET, ClusterV4ControllerCountService::new(handler))); + self + } + + /// GET /api/v4/{network}/clusters + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerListPath,super::endpoint::ClusterV4ControllerListQuery) -> ClusterV4ControllerListResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_list(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerListPath,super::endpoint::ClusterV4ControllerListQuery, ...extractors) -> ClusterV4ControllerListResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_list(handler); + /// ``` + pub fn cluster_v4_controller_list(mut self, handler: H) -> Self + where + H: ClusterV4ControllerListHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/clusters", on_service(MethodFilter::GET, ClusterV4ControllerListService::new(handler))); + self + } + + /// GET /api/v4/{network}/clusters/updates + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerUpdatesPath,super::endpoint::ClusterV4ControllerUpdatesQuery) -> ClusterV4ControllerUpdatesResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_updates(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerUpdatesPath,super::endpoint::ClusterV4ControllerUpdatesQuery, ...extractors) -> ClusterV4ControllerUpdatesResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_updates(handler); + /// ``` + pub fn cluster_v4_controller_updates(mut self, handler: H) -> Self + where + H: ClusterV4ControllerUpdatesHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/clusters/updates", on_service(MethodFilter::GET, ClusterV4ControllerUpdatesService::new(handler))); + self + } + + /// GET /api/v4/{network}/clusters/{id} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerByIdPath,super::endpoint::ClusterV4ControllerByIdQuery) -> ClusterV4ControllerByIdResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_by_id(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerByIdPath,super::endpoint::ClusterV4ControllerByIdQuery, ...extractors) -> ClusterV4ControllerByIdResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_by_id(handler); + /// ``` + pub fn cluster_v4_controller_by_id(mut self, handler: H) -> Self + where + H: ClusterV4ControllerByIdHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/clusters/:id", on_service(MethodFilter::GET, ClusterV4ControllerByIdService::new(handler))); + self + } + + /// GET /api/v4/{network}/clusters/owner/{owner}/operators/{operators} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerByOwnerAndOperatorsPath,super::endpoint::ClusterV4ControllerByOwnerAndOperatorsQuery) -> ClusterV4ControllerByOwnerAndOperatorsResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_by_owner_and_operators(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerByOwnerAndOperatorsPath,super::endpoint::ClusterV4ControllerByOwnerAndOperatorsQuery, ...extractors) -> ClusterV4ControllerByOwnerAndOperatorsResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_by_owner_and_operators(handler); + /// ``` + pub fn cluster_v4_controller_by_owner_and_operators(mut self, handler: H) -> Self + where + H: ClusterV4ControllerByOwnerAndOperatorsHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/clusters/owner/:owner/operators/:operators", on_service(MethodFilter::GET, ClusterV4ControllerByOwnerAndOperatorsService::new(handler))); + self + } + + /// GET /api/v4/{network}/clusters/owner/{owner} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerByOwnerPath,super::endpoint::ClusterV4ControllerByOwnerQuery) -> ClusterV4ControllerByOwnerResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_by_owner(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerByOwnerPath,super::endpoint::ClusterV4ControllerByOwnerQuery, ...extractors) -> ClusterV4ControllerByOwnerResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_by_owner(handler); + /// ``` + pub fn cluster_v4_controller_by_owner(mut self, handler: H) -> Self + where + H: ClusterV4ControllerByOwnerHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/clusters/owner/:owner", on_service(MethodFilter::GET, ClusterV4ControllerByOwnerService::new(handler))); + self + } + + /// GET /api/v4/{network}/clusters/hash/{clusterHash} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerValidatorsPath,super::endpoint::ClusterV4ControllerValidatorsQuery) -> ClusterV4ControllerValidatorsResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_validators(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ClusterV4ControllerValidatorsPath,super::endpoint::ClusterV4ControllerValidatorsQuery, ...extractors) -> ClusterV4ControllerValidatorsResponse { + /// todo!(); + /// } + /// let router = ClustersRouter::default().cluster_v4_controller_validators(handler); + /// ``` + pub fn cluster_v4_controller_validators(mut self, handler: H) -> Self + where + H: ClusterV4ControllerValidatorsHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/clusters/hash/:clusterHash", on_service(MethodFilter::GET, ClusterV4ControllerValidatorsService::new(handler))); + self + } +} + +impl Default for ClustersRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: ClustersRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/clusters/count handler +pub trait ClusterV4ControllerCountHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ClusterV4ControllerCountHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ClusterV4ControllerCountPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::ClusterV4ControllerCountResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! cluster_v4_controller_count_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ClusterV4ControllerCountHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ClusterV4ControllerCountPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::ClusterV4ControllerCountResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(cluster_v4_controller_count_handler); + +/// GET /api/v4/{network}/clusters/count service +struct ClusterV4ControllerCountService +where + H: ClusterV4ControllerCountHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ClusterV4ControllerCountService +where + H: ClusterV4ControllerCountHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ClusterV4ControllerCountService +where + H: ClusterV4ControllerCountHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ClusterV4ControllerCountService +where + H: ClusterV4ControllerCountHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ClusterV4ControllerCountHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/clusters handler +pub trait ClusterV4ControllerListHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ClusterV4ControllerListHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ClusterV4ControllerListPath,super::endpoint::ClusterV4ControllerListQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::ClusterV4ControllerListResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! cluster_v4_controller_list_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ClusterV4ControllerListHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ClusterV4ControllerListPath,super::endpoint::ClusterV4ControllerListQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::ClusterV4ControllerListResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(cluster_v4_controller_list_handler); + +/// GET /api/v4/{network}/clusters service +struct ClusterV4ControllerListService +where + H: ClusterV4ControllerListHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ClusterV4ControllerListService +where + H: ClusterV4ControllerListHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ClusterV4ControllerListService +where + H: ClusterV4ControllerListHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ClusterV4ControllerListService +where + H: ClusterV4ControllerListHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ClusterV4ControllerListHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/clusters/updates handler +pub trait ClusterV4ControllerUpdatesHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ClusterV4ControllerUpdatesHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ClusterV4ControllerUpdatesPath,super::endpoint::ClusterV4ControllerUpdatesQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::ClusterV4ControllerUpdatesResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! cluster_v4_controller_updates_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ClusterV4ControllerUpdatesHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ClusterV4ControllerUpdatesPath,super::endpoint::ClusterV4ControllerUpdatesQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::ClusterV4ControllerUpdatesResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(cluster_v4_controller_updates_handler); + +/// GET /api/v4/{network}/clusters/updates service +struct ClusterV4ControllerUpdatesService +where + H: ClusterV4ControllerUpdatesHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ClusterV4ControllerUpdatesService +where + H: ClusterV4ControllerUpdatesHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ClusterV4ControllerUpdatesService +where + H: ClusterV4ControllerUpdatesHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ClusterV4ControllerUpdatesService +where + H: ClusterV4ControllerUpdatesHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ClusterV4ControllerUpdatesHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/clusters/{id} handler +pub trait ClusterV4ControllerByIdHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ClusterV4ControllerByIdHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ClusterV4ControllerByIdPath,super::endpoint::ClusterV4ControllerByIdQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::ClusterV4ControllerByIdResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! cluster_v4_controller_by_id_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ClusterV4ControllerByIdHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ClusterV4ControllerByIdPath,super::endpoint::ClusterV4ControllerByIdQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::ClusterV4ControllerByIdResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(cluster_v4_controller_by_id_handler); + +/// GET /api/v4/{network}/clusters/{id} service +struct ClusterV4ControllerByIdService +where + H: ClusterV4ControllerByIdHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ClusterV4ControllerByIdService +where + H: ClusterV4ControllerByIdHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ClusterV4ControllerByIdService +where + H: ClusterV4ControllerByIdHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ClusterV4ControllerByIdService +where + H: ClusterV4ControllerByIdHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ClusterV4ControllerByIdHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/clusters/owner/{owner}/operators/{operators} handler +pub trait ClusterV4ControllerByOwnerAndOperatorsHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ClusterV4ControllerByOwnerAndOperatorsHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ClusterV4ControllerByOwnerAndOperatorsPath,super::endpoint::ClusterV4ControllerByOwnerAndOperatorsQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::ClusterV4ControllerByOwnerAndOperatorsResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! cluster_v4_controller_by_owner_and_operators_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ClusterV4ControllerByOwnerAndOperatorsHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ClusterV4ControllerByOwnerAndOperatorsPath,super::endpoint::ClusterV4ControllerByOwnerAndOperatorsQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::ClusterV4ControllerByOwnerAndOperatorsResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(cluster_v4_controller_by_owner_and_operators_handler); + +/// GET /api/v4/{network}/clusters/owner/{owner}/operators/{operators} service +struct ClusterV4ControllerByOwnerAndOperatorsService +where + H: ClusterV4ControllerByOwnerAndOperatorsHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ClusterV4ControllerByOwnerAndOperatorsService +where + H: ClusterV4ControllerByOwnerAndOperatorsHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ClusterV4ControllerByOwnerAndOperatorsService +where + H: ClusterV4ControllerByOwnerAndOperatorsHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ClusterV4ControllerByOwnerAndOperatorsService +where + H: ClusterV4ControllerByOwnerAndOperatorsHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ClusterV4ControllerByOwnerAndOperatorsHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/clusters/owner/{owner} handler +pub trait ClusterV4ControllerByOwnerHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ClusterV4ControllerByOwnerHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ClusterV4ControllerByOwnerPath,super::endpoint::ClusterV4ControllerByOwnerQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::ClusterV4ControllerByOwnerResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! cluster_v4_controller_by_owner_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ClusterV4ControllerByOwnerHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ClusterV4ControllerByOwnerPath,super::endpoint::ClusterV4ControllerByOwnerQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::ClusterV4ControllerByOwnerResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(cluster_v4_controller_by_owner_handler); + +/// GET /api/v4/{network}/clusters/owner/{owner} service +struct ClusterV4ControllerByOwnerService +where + H: ClusterV4ControllerByOwnerHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ClusterV4ControllerByOwnerService +where + H: ClusterV4ControllerByOwnerHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ClusterV4ControllerByOwnerService +where + H: ClusterV4ControllerByOwnerHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ClusterV4ControllerByOwnerService +where + H: ClusterV4ControllerByOwnerHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ClusterV4ControllerByOwnerHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/clusters/hash/{clusterHash} handler +pub trait ClusterV4ControllerValidatorsHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ClusterV4ControllerValidatorsHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ClusterV4ControllerValidatorsPath,super::endpoint::ClusterV4ControllerValidatorsQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::ClusterV4ControllerValidatorsResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! cluster_v4_controller_validators_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ClusterV4ControllerValidatorsHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ClusterV4ControllerValidatorsPath,super::endpoint::ClusterV4ControllerValidatorsQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::ClusterV4ControllerValidatorsResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(cluster_v4_controller_validators_handler); + +/// GET /api/v4/{network}/clusters/hash/{clusterHash} service +struct ClusterV4ControllerValidatorsService +where + H: ClusterV4ControllerValidatorsHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ClusterV4ControllerValidatorsService +where + H: ClusterV4ControllerValidatorsHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ClusterV4ControllerValidatorsService +where + H: ClusterV4ControllerValidatorsHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ClusterV4ControllerValidatorsService +where + H: ClusterV4ControllerValidatorsHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ClusterV4ControllerValidatorsHandler::call(handler, req, state).await) + }) + } +} + + + +/// Duties router +pub struct DutiesRouter { + pub(crate) router: Router, +} + +impl DutiesRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/duties/{validator} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::DutiesV4ControllerDutiesPath,super::endpoint::DutiesV4ControllerDutiesQuery) -> DutiesV4ControllerDutiesResponse { + /// todo!(); + /// } + /// let router = DutiesRouter::default().duties_v4_controller_duties(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::DutiesV4ControllerDutiesPath,super::endpoint::DutiesV4ControllerDutiesQuery, ...extractors) -> DutiesV4ControllerDutiesResponse { + /// todo!(); + /// } + /// let router = DutiesRouter::default().duties_v4_controller_duties(handler); + /// ``` + pub fn duties_v4_controller_duties(mut self, handler: H) -> Self + where + H: DutiesV4ControllerDutiesHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/duties/:validator", on_service(MethodFilter::GET, DutiesV4ControllerDutiesService::new(handler))); + self + } +} + +impl Default for DutiesRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: DutiesRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/duties/{validator} handler +pub trait DutiesV4ControllerDutiesHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl DutiesV4ControllerDutiesHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::DutiesV4ControllerDutiesPath,super::endpoint::DutiesV4ControllerDutiesQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::DutiesV4ControllerDutiesResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! duties_v4_controller_duties_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl DutiesV4ControllerDutiesHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::DutiesV4ControllerDutiesPath,super::endpoint::DutiesV4ControllerDutiesQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::DutiesV4ControllerDutiesResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(duties_v4_controller_duties_handler); + +/// GET /api/v4/{network}/duties/{validator} service +struct DutiesV4ControllerDutiesService +where + H: DutiesV4ControllerDutiesHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for DutiesV4ControllerDutiesService +where + H: DutiesV4ControllerDutiesHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl DutiesV4ControllerDutiesService +where + H: DutiesV4ControllerDutiesHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for DutiesV4ControllerDutiesService +where + H: DutiesV4ControllerDutiesHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( DutiesV4ControllerDutiesHandler::call(handler, req, state).await) + }) + } +} + + + +/// Events router +pub struct EventsRouter { + pub(crate) router: Router, +} + +impl EventsRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/events/{txHash} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4EventsGetPath) -> ApiV4EventsGetResponse { + /// todo!(); + /// } + /// let router = EventsRouter::default().api_v4_events_get(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4EventsGetPath, ...extractors) -> ApiV4EventsGetResponse { + /// todo!(); + /// } + /// let router = EventsRouter::default().api_v4_events_get(handler); + /// ``` + pub fn api_v4_events_get(mut self, handler: H) -> Self + where + H: ApiV4EventsGetHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/events/:txHash", on_service(MethodFilter::GET, ApiV4EventsGetService::new(handler))); + self + } +} + +impl Default for EventsRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: EventsRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/events/{txHash} handler +pub trait ApiV4EventsGetHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ApiV4EventsGetHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ApiV4EventsGetPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::ApiV4EventsGetResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! api_v4_events_get_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ApiV4EventsGetHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ApiV4EventsGetPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::ApiV4EventsGetResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(api_v4_events_get_handler); + +/// GET /api/v4/{network}/events/{txHash} service +struct ApiV4EventsGetService +where + H: ApiV4EventsGetHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ApiV4EventsGetService +where + H: ApiV4EventsGetHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ApiV4EventsGetService +where + H: ApiV4EventsGetHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ApiV4EventsGetService +where + H: ApiV4EventsGetHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ApiV4EventsGetHandler::call(handler, req, state).await) + }) + } +} + + + +/// Faucet router +pub struct FaucetRouter { + pub(crate) router: Router, +} + +impl FaucetRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/faucet + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::FaucetControllerGetTransactionsPath) -> FaucetControllerGetTransactionsResponse { + /// todo!(); + /// } + /// let router = FaucetRouter::default().faucet_controller_get_transactions(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::FaucetControllerGetTransactionsPath, ...extractors) -> FaucetControllerGetTransactionsResponse { + /// todo!(); + /// } + /// let router = FaucetRouter::default().faucet_controller_get_transactions(handler); + /// ``` + pub fn faucet_controller_get_transactions(mut self, handler: H) -> Self + where + H: FaucetControllerGetTransactionsHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/faucet", on_service(MethodFilter::GET, FaucetControllerGetTransactionsService::new(handler))); + self + } + + /// POST /api/v4/{network}/faucet + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::FaucetControllerSetTransactionPath,super::model::FaucetControllerSetTransactionRequestBody) -> FaucetControllerSetTransactionResponse { + /// todo!(); + /// } + /// let router = FaucetRouter::default().faucet_controller_set_transaction(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::FaucetControllerSetTransactionPath,super::model::FaucetControllerSetTransactionRequestBody, ...extractors) -> FaucetControllerSetTransactionResponse { + /// todo!(); + /// } + /// let router = FaucetRouter::default().faucet_controller_set_transaction(handler); + /// ``` + pub fn faucet_controller_set_transaction(mut self, handler: H) -> Self + where + H: FaucetControllerSetTransactionHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/faucet", on_service(MethodFilter::POST, FaucetControllerSetTransactionService::new(handler))); + self + } + + /// GET /api/v4/{network}/faucet/config + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::FaucetControllerGetFaucetConfigPath) -> FaucetControllerGetFaucetConfigResponse { + /// todo!(); + /// } + /// let router = FaucetRouter::default().faucet_controller_get_faucet_config(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::FaucetControllerGetFaucetConfigPath, ...extractors) -> FaucetControllerGetFaucetConfigResponse { + /// todo!(); + /// } + /// let router = FaucetRouter::default().faucet_controller_get_faucet_config(handler); + /// ``` + pub fn faucet_controller_get_faucet_config(mut self, handler: H) -> Self + where + H: FaucetControllerGetFaucetConfigHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/faucet/config", on_service(MethodFilter::GET, FaucetControllerGetFaucetConfigService::new(handler))); + self + } +} + +impl Default for FaucetRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: FaucetRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/faucet handler +pub trait FaucetControllerGetTransactionsHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl FaucetControllerGetTransactionsHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::FaucetControllerGetTransactionsPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::FaucetControllerGetTransactionsResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! faucet_controller_get_transactions_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl FaucetControllerGetTransactionsHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::FaucetControllerGetTransactionsPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::FaucetControllerGetTransactionsResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(faucet_controller_get_transactions_handler); + +/// GET /api/v4/{network}/faucet service +struct FaucetControllerGetTransactionsService +where + H: FaucetControllerGetTransactionsHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for FaucetControllerGetTransactionsService +where + H: FaucetControllerGetTransactionsHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl FaucetControllerGetTransactionsService +where + H: FaucetControllerGetTransactionsHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for FaucetControllerGetTransactionsService +where + H: FaucetControllerGetTransactionsHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( FaucetControllerGetTransactionsHandler::call(handler, req, state).await) + }) + } +} + + +/// POST /api/v4/{network}/faucet handler +pub trait FaucetControllerSetTransactionHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl FaucetControllerSetTransactionHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::FaucetControllerSetTransactionPath,super::model::FaucetControllerSetTransactionRequestBody,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, ).await; + + let response: super::endpoint::FaucetControllerSetTransactionResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! faucet_controller_set_transaction_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl FaucetControllerSetTransactionHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::FaucetControllerSetTransactionPath,super::model::FaucetControllerSetTransactionRequestBody,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into,B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, $($ty,)*).await; + + let response: super::endpoint::FaucetControllerSetTransactionResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(faucet_controller_set_transaction_handler); + +/// POST /api/v4/{network}/faucet service +struct FaucetControllerSetTransactionService +where + H: FaucetControllerSetTransactionHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for FaucetControllerSetTransactionService +where + H: FaucetControllerSetTransactionHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl FaucetControllerSetTransactionService +where + H: FaucetControllerSetTransactionHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for FaucetControllerSetTransactionService +where + H: FaucetControllerSetTransactionHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( FaucetControllerSetTransactionHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/faucet/config handler +pub trait FaucetControllerGetFaucetConfigHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl FaucetControllerGetFaucetConfigHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::FaucetControllerGetFaucetConfigPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::FaucetControllerGetFaucetConfigResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! faucet_controller_get_faucet_config_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl FaucetControllerGetFaucetConfigHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::FaucetControllerGetFaucetConfigPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::FaucetControllerGetFaucetConfigResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(faucet_controller_get_faucet_config_handler); + +/// GET /api/v4/{network}/faucet/config service +struct FaucetControllerGetFaucetConfigService +where + H: FaucetControllerGetFaucetConfigHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for FaucetControllerGetFaucetConfigService +where + H: FaucetControllerGetFaucetConfigHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl FaucetControllerGetFaucetConfigService +where + H: FaucetControllerGetFaucetConfigHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for FaucetControllerGetFaucetConfigService +where + H: FaucetControllerGetFaucetConfigHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( FaucetControllerGetFaucetConfigHandler::call(handler, req, state).await) + }) + } +} + + + +/// Finance router +pub struct FinanceRouter { + pub(crate) router: Router, +} + +impl FinanceRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/finance/currency/convert/{symbol}/{quote} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::FinanceControllerCurrencyConvertPath) -> FinanceControllerCurrencyConvertResponse { + /// todo!(); + /// } + /// let router = FinanceRouter::default().finance_controller_currency_convert(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::FinanceControllerCurrencyConvertPath, ...extractors) -> FinanceControllerCurrencyConvertResponse { + /// todo!(); + /// } + /// let router = FinanceRouter::default().finance_controller_currency_convert(handler); + /// ``` + pub fn finance_controller_currency_convert(mut self, handler: H) -> Self + where + H: FinanceControllerCurrencyConvertHandler, + T: 'static + { + self.router = self.router.route("/api/finance/currency/convert/:symbol/:quote", on_service(MethodFilter::GET, FinanceControllerCurrencyConvertService::new(handler))); + self + } +} + +impl Default for FinanceRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: FinanceRouter) -> Self { + r.router + } +} + +/// GET /api/finance/currency/convert/{symbol}/{quote} handler +pub trait FinanceControllerCurrencyConvertHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl FinanceControllerCurrencyConvertHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::FinanceControllerCurrencyConvertPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::FinanceControllerCurrencyConvertResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! finance_controller_currency_convert_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl FinanceControllerCurrencyConvertHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::FinanceControllerCurrencyConvertPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::FinanceControllerCurrencyConvertResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(finance_controller_currency_convert_handler); + +/// GET /api/finance/currency/convert/{symbol}/{quote} service +struct FinanceControllerCurrencyConvertService +where + H: FinanceControllerCurrencyConvertHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for FinanceControllerCurrencyConvertService +where + H: FinanceControllerCurrencyConvertHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl FinanceControllerCurrencyConvertService +where + H: FinanceControllerCurrencyConvertHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for FinanceControllerCurrencyConvertService +where + H: FinanceControllerCurrencyConvertHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( FinanceControllerCurrencyConvertHandler::call(handler, req, state).await) + }) + } +} + + + +/// Graph router +pub struct GraphRouter { + pub(crate) router: Router, +} + +impl GraphRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/operators/graph + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGraphPath,super::endpoint::OperatorsV4ControllerGraphQuery) -> OperatorsV4ControllerGraphResponse { + /// todo!(); + /// } + /// let router = GraphRouter::default().operators_v4_controller_graph(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGraphPath,super::endpoint::OperatorsV4ControllerGraphQuery, ...extractors) -> OperatorsV4ControllerGraphResponse { + /// todo!(); + /// } + /// let router = GraphRouter::default().operators_v4_controller_graph(handler); + /// ``` + pub fn operators_v4_controller_graph(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerGraphHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/graph", on_service(MethodFilter::GET, OperatorsV4ControllerGraphService::new(handler))); + self + } +} + +impl Default for GraphRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: GraphRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/operators/graph handler +pub trait OperatorsV4ControllerGraphHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerGraphHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerGraphPath,super::endpoint::OperatorsV4ControllerGraphQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerGraphResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_graph_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerGraphHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerGraphPath,super::endpoint::OperatorsV4ControllerGraphQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerGraphResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_graph_handler); + +/// GET /api/v4/{network}/operators/graph service +struct OperatorsV4ControllerGraphService +where + H: OperatorsV4ControllerGraphHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerGraphService +where + H: OperatorsV4ControllerGraphHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerGraphService +where + H: OperatorsV4ControllerGraphHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerGraphService +where + H: OperatorsV4ControllerGraphHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerGraphHandler::call(handler, req, state).await) + }) + } +} + + + +/// Health router +pub struct HealthRouter { + pub(crate) router: Router, +} + +impl HealthRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/health + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::HealthV4ControllerHealthPath) -> HealthV4ControllerHealthResponse { + /// todo!(); + /// } + /// let router = HealthRouter::default().health_v4_controller_health(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::HealthV4ControllerHealthPath, ...extractors) -> HealthV4ControllerHealthResponse { + /// todo!(); + /// } + /// let router = HealthRouter::default().health_v4_controller_health(handler); + /// ``` + pub fn health_v4_controller_health(mut self, handler: H) -> Self + where + H: HealthV4ControllerHealthHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/health", on_service(MethodFilter::GET, HealthV4ControllerHealthService::new(handler))); + self + } +} + +impl Default for HealthRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: HealthRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/health handler +pub trait HealthV4ControllerHealthHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl HealthV4ControllerHealthHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::HealthV4ControllerHealthPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::HealthV4ControllerHealthResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! health_v4_controller_health_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl HealthV4ControllerHealthHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::HealthV4ControllerHealthPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::HealthV4ControllerHealthResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(health_v4_controller_health_handler); + +/// GET /api/v4/{network}/health service +struct HealthV4ControllerHealthService +where + H: HealthV4ControllerHealthHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for HealthV4ControllerHealthService +where + H: HealthV4ControllerHealthHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl HealthV4ControllerHealthService +where + H: HealthV4ControllerHealthHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for HealthV4ControllerHealthService +where + H: HealthV4ControllerHealthHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( HealthV4ControllerHealthHandler::call(handler, req, state).await) + }) + } +} + + + +/// Incentivized router +pub struct IncentivizedRouter { + pub(crate) router: Router, +} + +impl IncentivizedRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/incentivization/merkle-tree + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionPath) -> IncentivizationV4ControllerMigrationOperatorsDistributionResponse { + /// todo!(); + /// } + /// let router = IncentivizedRouter::default().incentivization_v4_controller_migration_operators_distribution(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionPath, ...extractors) -> IncentivizationV4ControllerMigrationOperatorsDistributionResponse { + /// todo!(); + /// } + /// let router = IncentivizedRouter::default().incentivization_v4_controller_migration_operators_distribution(handler); + /// ``` + pub fn incentivization_v4_controller_migration_operators_distribution(mut self, handler: H) -> Self + where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/incentivization/merkle-tree", on_service(MethodFilter::GET, IncentivizationV4ControllerMigrationOperatorsDistributionService::new(handler))); + self + } +} + +impl Default for IncentivizedRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: IncentivizedRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/incentivization/merkle-tree handler +pub trait IncentivizationV4ControllerMigrationOperatorsDistributionHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl IncentivizationV4ControllerMigrationOperatorsDistributionHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! incentivization_v4_controller_migration_operators_distribution_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl IncentivizationV4ControllerMigrationOperatorsDistributionHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(incentivization_v4_controller_migration_operators_distribution_handler); + +/// GET /api/v4/{network}/incentivization/merkle-tree service +struct IncentivizationV4ControllerMigrationOperatorsDistributionService +where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for IncentivizationV4ControllerMigrationOperatorsDistributionService +where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl IncentivizationV4ControllerMigrationOperatorsDistributionService +where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for IncentivizationV4ControllerMigrationOperatorsDistributionService +where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( IncentivizationV4ControllerMigrationOperatorsDistributionHandler::call(handler, req, state).await) + }) + } +} + + + +/// Operators router +pub struct OperatorsRouter { + pub(crate) router: Router, +} + +impl OperatorsRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/operators/graph + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGraphPath,super::endpoint::OperatorsV4ControllerGraphQuery) -> OperatorsV4ControllerGraphResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_graph(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGraphPath,super::endpoint::OperatorsV4ControllerGraphQuery, ...extractors) -> OperatorsV4ControllerGraphResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_graph(handler); + /// ``` + pub fn operators_v4_controller_graph(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerGraphHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/graph", on_service(MethodFilter::GET, OperatorsV4ControllerGraphService::new(handler))); + self + } + + /// GET /api/v4/{network}/operators/owned_by/{ownerAddress} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerOwnedByPath,super::endpoint::OperatorsV4ControllerOwnedByQuery) -> OperatorsV4ControllerOwnedByResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_owned_by(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerOwnedByPath,super::endpoint::OperatorsV4ControllerOwnedByQuery, ...extractors) -> OperatorsV4ControllerOwnedByResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_owned_by(handler); + /// ``` + pub fn operators_v4_controller_owned_by(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerOwnedByHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/owned_by/:ownerAddress", on_service(MethodFilter::GET, OperatorsV4ControllerOwnedByService::new(handler))); + self + } + + /// GET /api/v4/{network}/operators/incentivized/{operator} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerIncentivizedPath,super::endpoint::OperatorsV4ControllerIncentivizedQuery) -> OperatorsV4ControllerIncentivizedResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_incentivized(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerIncentivizedPath,super::endpoint::OperatorsV4ControllerIncentivizedQuery, ...extractors) -> OperatorsV4ControllerIncentivizedResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_incentivized(handler); + /// ``` + pub fn operators_v4_controller_incentivized(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerIncentivizedHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/incentivized/:operator", on_service(MethodFilter::GET, OperatorsV4ControllerIncentivizedService::new(handler))); + self + } + + /// GET /api/v4/{network}/operators/{operator} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGetOperatorPath) -> OperatorsV4ControllerGetOperatorResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_get_operator(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGetOperatorPath, ...extractors) -> OperatorsV4ControllerGetOperatorResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_get_operator(handler); + /// ``` + pub fn operators_v4_controller_get_operator(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerGetOperatorHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/:operator", on_service(MethodFilter::GET, OperatorsV4ControllerGetOperatorService::new(handler))); + self + } + + /// POST /api/v4/{network}/operators/dkg_health_check + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGetDkgHealthCheckPath,super::model::OperatorsV4ControllerGetDkgHealthCheckRequestBody) -> OperatorsV4ControllerGetDkgHealthCheckResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_get_dkg_health_check(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGetDkgHealthCheckPath,super::model::OperatorsV4ControllerGetDkgHealthCheckRequestBody, ...extractors) -> OperatorsV4ControllerGetDkgHealthCheckResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_get_dkg_health_check(handler); + /// ``` + pub fn operators_v4_controller_get_dkg_health_check(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerGetDkgHealthCheckHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/dkg_health_check", on_service(MethodFilter::POST, OperatorsV4ControllerGetDkgHealthCheckService::new(handler))); + self + } + + /// GET /api/v4/{network}/operators/public_key/{public_key} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGetByPublicKeyPath) -> OperatorsV4ControllerGetByPublicKeyResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_get_by_public_key(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGetByPublicKeyPath, ...extractors) -> OperatorsV4ControllerGetByPublicKeyResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_get_by_public_key(handler); + /// ``` + pub fn operators_v4_controller_get_by_public_key(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerGetByPublicKeyHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/public_key/:public_key", on_service(MethodFilter::GET, OperatorsV4ControllerGetByPublicKeyService::new(handler))); + self + } + + /// GET /api/v4/{network}/operators + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerOperatorsPath,super::endpoint::OperatorsV4ControllerOperatorsQuery) -> OperatorsV4ControllerOperatorsResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_operators(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerOperatorsPath,super::endpoint::OperatorsV4ControllerOperatorsQuery, ...extractors) -> OperatorsV4ControllerOperatorsResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_operators(handler); + /// ``` + pub fn operators_v4_controller_operators(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerOperatorsHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators", on_service(MethodFilter::GET, OperatorsV4ControllerOperatorsService::new(handler))); + self + } + + /// POST /api/v4/{network}/operators + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGetByIdsPath,super::model::OperatorsV4ControllerGetByIdsRequestBody) -> OperatorsV4ControllerGetByIdsResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_get_by_ids(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerGetByIdsPath,super::model::OperatorsV4ControllerGetByIdsRequestBody, ...extractors) -> OperatorsV4ControllerGetByIdsResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_get_by_ids(handler); + /// ``` + pub fn operators_v4_controller_get_by_ids(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerGetByIdsHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators", on_service(MethodFilter::POST, OperatorsV4ControllerGetByIdsService::new(handler))); + self + } + + /// PUT /api/v4/{network}/operators/{operator}/metadata + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerUpdateMetadataPath,super::model::OperatorsV4ControllerUpdateMetadataRequestBody) -> OperatorsV4ControllerUpdateMetadataResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_update_metadata(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerUpdateMetadataPath,super::model::OperatorsV4ControllerUpdateMetadataRequestBody, ...extractors) -> OperatorsV4ControllerUpdateMetadataResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_update_metadata(handler); + /// ``` + pub fn operators_v4_controller_update_metadata(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerUpdateMetadataHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/:operator/metadata", on_service(MethodFilter::PUT, OperatorsV4ControllerUpdateMetadataService::new(handler))); + self + } + + /// GET /api/v4/{network}/operators/nodes/{layer} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerNodesPath) -> OperatorsV4ControllerNodesResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_nodes(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerNodesPath, ...extractors) -> OperatorsV4ControllerNodesResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_nodes(handler); + /// ``` + pub fn operators_v4_controller_nodes(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerNodesHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/nodes/:layer", on_service(MethodFilter::GET, OperatorsV4ControllerNodesService::new(handler))); + self + } + + /// GET /api/v4/{network}/operators/locations + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerLocationsPath) -> OperatorsV4ControllerLocationsResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_locations(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::OperatorsV4ControllerLocationsPath, ...extractors) -> OperatorsV4ControllerLocationsResponse { + /// todo!(); + /// } + /// let router = OperatorsRouter::default().operators_v4_controller_locations(handler); + /// ``` + pub fn operators_v4_controller_locations(mut self, handler: H) -> Self + where + H: OperatorsV4ControllerLocationsHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/operators/locations", on_service(MethodFilter::GET, OperatorsV4ControllerLocationsService::new(handler))); + self + } +} + +impl Default for OperatorsRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: OperatorsRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/operators/graph handler +pub trait OperatorsV4ControllerGraphHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerGraphHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerGraphPath,super::endpoint::OperatorsV4ControllerGraphQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerGraphResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_graph_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerGraphHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerGraphPath,super::endpoint::OperatorsV4ControllerGraphQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerGraphResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_graph_handler); + +/// GET /api/v4/{network}/operators/graph service +struct OperatorsV4ControllerGraphService +where + H: OperatorsV4ControllerGraphHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerGraphService +where + H: OperatorsV4ControllerGraphHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerGraphService +where + H: OperatorsV4ControllerGraphHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerGraphService +where + H: OperatorsV4ControllerGraphHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerGraphHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/operators/owned_by/{ownerAddress} handler +pub trait OperatorsV4ControllerOwnedByHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerOwnedByHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerOwnedByPath,super::endpoint::OperatorsV4ControllerOwnedByQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerOwnedByResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_owned_by_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerOwnedByHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerOwnedByPath,super::endpoint::OperatorsV4ControllerOwnedByQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerOwnedByResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_owned_by_handler); + +/// GET /api/v4/{network}/operators/owned_by/{ownerAddress} service +struct OperatorsV4ControllerOwnedByService +where + H: OperatorsV4ControllerOwnedByHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerOwnedByService +where + H: OperatorsV4ControllerOwnedByHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerOwnedByService +where + H: OperatorsV4ControllerOwnedByHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerOwnedByService +where + H: OperatorsV4ControllerOwnedByHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerOwnedByHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/operators/incentivized/{operator} handler +pub trait OperatorsV4ControllerIncentivizedHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerIncentivizedHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerIncentivizedPath,super::endpoint::OperatorsV4ControllerIncentivizedQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerIncentivizedResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_incentivized_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerIncentivizedHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerIncentivizedPath,super::endpoint::OperatorsV4ControllerIncentivizedQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerIncentivizedResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_incentivized_handler); + +/// GET /api/v4/{network}/operators/incentivized/{operator} service +struct OperatorsV4ControllerIncentivizedService +where + H: OperatorsV4ControllerIncentivizedHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerIncentivizedService +where + H: OperatorsV4ControllerIncentivizedHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerIncentivizedService +where + H: OperatorsV4ControllerIncentivizedHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerIncentivizedService +where + H: OperatorsV4ControllerIncentivizedHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerIncentivizedHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/operators/{operator} handler +pub trait OperatorsV4ControllerGetOperatorHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerGetOperatorHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerGetOperatorPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerGetOperatorResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_get_operator_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerGetOperatorHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerGetOperatorPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerGetOperatorResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_get_operator_handler); + +/// GET /api/v4/{network}/operators/{operator} service +struct OperatorsV4ControllerGetOperatorService +where + H: OperatorsV4ControllerGetOperatorHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerGetOperatorService +where + H: OperatorsV4ControllerGetOperatorHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerGetOperatorService +where + H: OperatorsV4ControllerGetOperatorHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerGetOperatorService +where + H: OperatorsV4ControllerGetOperatorHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerGetOperatorHandler::call(handler, req, state).await) + }) + } +} + + +/// POST /api/v4/{network}/operators/dkg_health_check handler +pub trait OperatorsV4ControllerGetDkgHealthCheckHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerGetDkgHealthCheckHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerGetDkgHealthCheckPath,super::model::OperatorsV4ControllerGetDkgHealthCheckRequestBody,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerGetDkgHealthCheckResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_get_dkg_health_check_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerGetDkgHealthCheckHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerGetDkgHealthCheckPath,super::model::OperatorsV4ControllerGetDkgHealthCheckRequestBody,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into,B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerGetDkgHealthCheckResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_get_dkg_health_check_handler); + +/// POST /api/v4/{network}/operators/dkg_health_check service +struct OperatorsV4ControllerGetDkgHealthCheckService +where + H: OperatorsV4ControllerGetDkgHealthCheckHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerGetDkgHealthCheckService +where + H: OperatorsV4ControllerGetDkgHealthCheckHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerGetDkgHealthCheckService +where + H: OperatorsV4ControllerGetDkgHealthCheckHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerGetDkgHealthCheckService +where + H: OperatorsV4ControllerGetDkgHealthCheckHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerGetDkgHealthCheckHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/operators/public_key/{public_key} handler +pub trait OperatorsV4ControllerGetByPublicKeyHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerGetByPublicKeyHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerGetByPublicKeyPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerGetByPublicKeyResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_get_by_public_key_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerGetByPublicKeyHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerGetByPublicKeyPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerGetByPublicKeyResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_get_by_public_key_handler); + +/// GET /api/v4/{network}/operators/public_key/{public_key} service +struct OperatorsV4ControllerGetByPublicKeyService +where + H: OperatorsV4ControllerGetByPublicKeyHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerGetByPublicKeyService +where + H: OperatorsV4ControllerGetByPublicKeyHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerGetByPublicKeyService +where + H: OperatorsV4ControllerGetByPublicKeyHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerGetByPublicKeyService +where + H: OperatorsV4ControllerGetByPublicKeyHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerGetByPublicKeyHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/operators handler +pub trait OperatorsV4ControllerOperatorsHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerOperatorsHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerOperatorsPath,super::endpoint::OperatorsV4ControllerOperatorsQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerOperatorsResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_operators_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerOperatorsHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerOperatorsPath,super::endpoint::OperatorsV4ControllerOperatorsQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerOperatorsResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_operators_handler); + +/// GET /api/v4/{network}/operators service +struct OperatorsV4ControllerOperatorsService +where + H: OperatorsV4ControllerOperatorsHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerOperatorsService +where + H: OperatorsV4ControllerOperatorsHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerOperatorsService +where + H: OperatorsV4ControllerOperatorsHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerOperatorsService +where + H: OperatorsV4ControllerOperatorsHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerOperatorsHandler::call(handler, req, state).await) + }) + } +} + + +/// POST /api/v4/{network}/operators handler +pub trait OperatorsV4ControllerGetByIdsHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerGetByIdsHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerGetByIdsPath,super::model::OperatorsV4ControllerGetByIdsRequestBody,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerGetByIdsResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_get_by_ids_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerGetByIdsHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerGetByIdsPath,super::model::OperatorsV4ControllerGetByIdsRequestBody,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into,B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerGetByIdsResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_get_by_ids_handler); + +/// POST /api/v4/{network}/operators service +struct OperatorsV4ControllerGetByIdsService +where + H: OperatorsV4ControllerGetByIdsHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerGetByIdsService +where + H: OperatorsV4ControllerGetByIdsHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerGetByIdsService +where + H: OperatorsV4ControllerGetByIdsHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerGetByIdsService +where + H: OperatorsV4ControllerGetByIdsHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerGetByIdsHandler::call(handler, req, state).await) + }) + } +} + + +/// PUT /api/v4/{network}/operators/{operator}/metadata handler +pub trait OperatorsV4ControllerUpdateMetadataHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerUpdateMetadataHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerUpdateMetadataPath,super::model::OperatorsV4ControllerUpdateMetadataRequestBody,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerUpdateMetadataResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_update_metadata_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerUpdateMetadataHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerUpdateMetadataPath,super::model::OperatorsV4ControllerUpdateMetadataRequestBody,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into,B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerUpdateMetadataResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_update_metadata_handler); + +/// PUT /api/v4/{network}/operators/{operator}/metadata service +struct OperatorsV4ControllerUpdateMetadataService +where + H: OperatorsV4ControllerUpdateMetadataHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerUpdateMetadataService +where + H: OperatorsV4ControllerUpdateMetadataHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerUpdateMetadataService +where + H: OperatorsV4ControllerUpdateMetadataHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerUpdateMetadataService +where + H: OperatorsV4ControllerUpdateMetadataHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerUpdateMetadataHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/operators/nodes/{layer} handler +pub trait OperatorsV4ControllerNodesHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerNodesHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerNodesPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerNodesResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_nodes_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerNodesHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerNodesPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerNodesResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_nodes_handler); + +/// GET /api/v4/{network}/operators/nodes/{layer} service +struct OperatorsV4ControllerNodesService +where + H: OperatorsV4ControllerNodesHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerNodesService +where + H: OperatorsV4ControllerNodesHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerNodesService +where + H: OperatorsV4ControllerNodesHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerNodesService +where + H: OperatorsV4ControllerNodesHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerNodesHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/operators/locations handler +pub trait OperatorsV4ControllerLocationsHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl OperatorsV4ControllerLocationsHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::OperatorsV4ControllerLocationsPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::OperatorsV4ControllerLocationsResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! operators_v4_controller_locations_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl OperatorsV4ControllerLocationsHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::OperatorsV4ControllerLocationsPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::OperatorsV4ControllerLocationsResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(operators_v4_controller_locations_handler); + +/// GET /api/v4/{network}/operators/locations service +struct OperatorsV4ControllerLocationsService +where + H: OperatorsV4ControllerLocationsHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for OperatorsV4ControllerLocationsService +where + H: OperatorsV4ControllerLocationsHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl OperatorsV4ControllerLocationsService +where + H: OperatorsV4ControllerLocationsHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for OperatorsV4ControllerLocationsService +where + H: OperatorsV4ControllerLocationsHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( OperatorsV4ControllerLocationsHandler::call(handler, req, state).await) + }) + } +} + + + +/// Search router +pub struct SearchRouter { + pub(crate) router: Router, +} + +impl SearchRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/search + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::SearchV4ControllerSearchPath,super::endpoint::SearchV4ControllerSearchQuery) -> SearchV4ControllerSearchResponse { + /// todo!(); + /// } + /// let router = SearchRouter::default().search_v4_controller_search(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::SearchV4ControllerSearchPath,super::endpoint::SearchV4ControllerSearchQuery, ...extractors) -> SearchV4ControllerSearchResponse { + /// todo!(); + /// } + /// let router = SearchRouter::default().search_v4_controller_search(handler); + /// ``` + pub fn search_v4_controller_search(mut self, handler: H) -> Self + where + H: SearchV4ControllerSearchHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/search", on_service(MethodFilter::GET, SearchV4ControllerSearchService::new(handler))); + self + } +} + +impl Default for SearchRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: SearchRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/search handler +pub trait SearchV4ControllerSearchHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl SearchV4ControllerSearchHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::SearchV4ControllerSearchPath,super::endpoint::SearchV4ControllerSearchQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::SearchV4ControllerSearchResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! search_v4_controller_search_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl SearchV4ControllerSearchHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::SearchV4ControllerSearchPath,super::endpoint::SearchV4ControllerSearchQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::SearchV4ControllerSearchResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(search_v4_controller_search_handler); + +/// GET /api/v4/{network}/search service +struct SearchV4ControllerSearchService +where + H: SearchV4ControllerSearchHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for SearchV4ControllerSearchService +where + H: SearchV4ControllerSearchHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl SearchV4ControllerSearchService +where + H: SearchV4ControllerSearchHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for SearchV4ControllerSearchService +where + H: SearchV4ControllerSearchHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( SearchV4ControllerSearchHandler::call(handler, req, state).await) + }) + } +} + + + +/// Validators router +pub struct ValidatorsRouter { + pub(crate) router: Router, +} + +impl ValidatorsRouter where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/validators/countActiveValidators + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::CountActiveValidatorsInNetworkPath) -> CountActiveValidatorsInNetworkResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().count_active_validators_in_network(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::CountActiveValidatorsInNetworkPath, ...extractors) -> CountActiveValidatorsInNetworkResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().count_active_validators_in_network(handler); + /// ``` + pub fn count_active_validators_in_network(mut self, handler: H) -> Self + where + H: CountActiveValidatorsInNetworkHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/countActiveValidators", on_service(MethodFilter::GET, CountActiveValidatorsInNetworkService::new(handler))); + self + } + + /// GET /api/v4/{network}/validators/owned_by/{ownerAddress}/cost + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerCostPath) -> ValidatorsV4ControllerCostResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_cost(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerCostPath, ...extractors) -> ValidatorsV4ControllerCostResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_cost(handler); + /// ``` + pub fn validators_v4_controller_cost(mut self, handler: H) -> Self + where + H: ValidatorsV4ControllerCostHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/owned_by/:ownerAddress/cost", on_service(MethodFilter::GET, ValidatorsV4ControllerCostService::new(handler))); + self + } + + /// GET /api/v4/{network}/validators/in_operator/{operator} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerInOperatorPath,super::endpoint::ValidatorsV4ControllerInOperatorQuery) -> ValidatorsV4ControllerInOperatorResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_in_operator(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerInOperatorPath,super::endpoint::ValidatorsV4ControllerInOperatorQuery, ...extractors) -> ValidatorsV4ControllerInOperatorResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_in_operator(handler); + /// ``` + pub fn validators_v4_controller_in_operator(mut self, handler: H) -> Self + where + H: ValidatorsV4ControllerInOperatorHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/in_operator/:operator", on_service(MethodFilter::GET, ValidatorsV4ControllerInOperatorService::new(handler))); + self + } + + /// GET /api/v4/{network}/validators/incentivized/{validator} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerIncentivizedPath,super::endpoint::ValidatorsV4ControllerIncentivizedQuery) -> ValidatorsV4ControllerIncentivizedResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_incentivized(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerIncentivizedPath,super::endpoint::ValidatorsV4ControllerIncentivizedQuery, ...extractors) -> ValidatorsV4ControllerIncentivizedResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_incentivized(handler); + /// ``` + pub fn validators_v4_controller_incentivized(mut self, handler: H) -> Self + where + H: ValidatorsV4ControllerIncentivizedHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/incentivized/:validator", on_service(MethodFilter::GET, ValidatorsV4ControllerIncentivizedService::new(handler))); + self + } + + /// GET /api/v4/{network}/validators/{validator} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerValidatorPath) -> ValidatorsV4ControllerValidatorResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_validator(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerValidatorPath, ...extractors) -> ValidatorsV4ControllerValidatorResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_validator(handler); + /// ``` + pub fn validators_v4_controller_validator(mut self, handler: H) -> Self + where + H: ValidatorsV4ControllerValidatorHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/:validator", on_service(MethodFilter::GET, ValidatorsV4ControllerValidatorService::new(handler))); + self + } + + /// GET /api/v4/{network}/validators/isRegisteredValidator/{validator} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerIsRegisteredValidatorPath) -> ValidatorsV4ControllerIsRegisteredValidatorResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_is_registered_validator(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerIsRegisteredValidatorPath, ...extractors) -> ValidatorsV4ControllerIsRegisteredValidatorResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_is_registered_validator(handler); + /// ``` + pub fn validators_v4_controller_is_registered_validator(mut self, handler: H) -> Self + where + H: ValidatorsV4ControllerIsRegisteredValidatorHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/isRegisteredValidator/:validator", on_service(MethodFilter::GET, ValidatorsV4ControllerIsRegisteredValidatorService::new(handler))); + self + } + + /// POST /api/v4/{network}/validators/registeredByPublicKeys + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4ValidatorRegisteredByPublicKeyCreatePath) -> ApiV4ValidatorRegisteredByPublicKeyCreateResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().api_v4_validator_registered_by_public_key_create(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4ValidatorRegisteredByPublicKeyCreatePath, ...extractors) -> ApiV4ValidatorRegisteredByPublicKeyCreateResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().api_v4_validator_registered_by_public_key_create(handler); + /// ``` + pub fn api_v4_validator_registered_by_public_key_create(mut self, handler: H) -> Self + where + H: ApiV4ValidatorRegisteredByPublicKeyCreateHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/registeredByPublicKeys", on_service(MethodFilter::POST, ApiV4ValidatorRegisteredByPublicKeyCreateService::new(handler))); + self + } + + /// GET /api/v4/{network}/validators + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerValidatorsPath,super::endpoint::ValidatorsV4ControllerValidatorsQuery) -> ValidatorsV4ControllerValidatorsResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_validators(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerValidatorsPath,super::endpoint::ValidatorsV4ControllerValidatorsQuery, ...extractors) -> ValidatorsV4ControllerValidatorsResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_validators(handler); + /// ``` + pub fn validators_v4_controller_validators(mut self, handler: H) -> Self + where + H: ValidatorsV4ControllerValidatorsHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators", on_service(MethodFilter::GET, ValidatorsV4ControllerValidatorsService::new(handler))); + self + } + + /// GET /api/v4/{network}/validators/duty_counts/{from_epoch}/{to_epoch} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerDutyCountsPath) -> ValidatorsV4ControllerDutyCountsResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_duty_counts(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ValidatorsV4ControllerDutyCountsPath, ...extractors) -> ValidatorsV4ControllerDutyCountsResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().validators_v4_controller_duty_counts(handler); + /// ``` + pub fn validators_v4_controller_duty_counts(mut self, handler: H) -> Self + where + H: ValidatorsV4ControllerDutyCountsHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/duty_counts/:from_epoch/:to_epoch", on_service(MethodFilter::GET, ValidatorsV4ControllerDutyCountsService::new(handler))); + self + } + + /// GET /api/v4/{network}/validators/validatorsByClusterHash/{clusterHash} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4ValidatorsValidatorsByClusterHashGetPath) -> ApiV4ValidatorsValidatorsByClusterHashGetResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().api_v4_validators_validators_by_cluster_hash_get(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4ValidatorsValidatorsByClusterHashGetPath, ...extractors) -> ApiV4ValidatorsValidatorsByClusterHashGetResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().api_v4_validators_validators_by_cluster_hash_get(handler); + /// ``` + pub fn api_v4_validators_validators_by_cluster_hash_get(mut self, handler: H) -> Self + where + H: ApiV4ValidatorsValidatorsByClusterHashGetHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/validatorsByClusterHash/:clusterHash", on_service(MethodFilter::GET, ApiV4ValidatorsValidatorsByClusterHashGetService::new(handler))); + self + } + + /// POST /api/v4/{network}/validators/validatorsWithdrawCredentials + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4ValidatorValidatorsWithdrawCredentialCreatePath,super::model::ApiV4ValidatorValidatorsWithdrawCredentialCreateRequestBody) -> ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().api_v4_validator_validators_withdraw_credential_create(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::ApiV4ValidatorValidatorsWithdrawCredentialCreatePath,super::model::ApiV4ValidatorValidatorsWithdrawCredentialCreateRequestBody, ...extractors) -> ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse { + /// todo!(); + /// } + /// let router = ValidatorsRouter::default().api_v4_validator_validators_withdraw_credential_create(handler); + /// ``` + pub fn api_v4_validator_validators_withdraw_credential_create(mut self, handler: H) -> Self + where + H: ApiV4ValidatorValidatorsWithdrawCredentialCreateHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/validators/validatorsWithdrawCredentials", on_service(MethodFilter::POST, ApiV4ValidatorValidatorsWithdrawCredentialCreateService::new(handler))); + self + } +} + +impl Default for ValidatorsRouter where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: ValidatorsRouter) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/validators/countActiveValidators handler +pub trait CountActiveValidatorsInNetworkHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl CountActiveValidatorsInNetworkHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::CountActiveValidatorsInNetworkPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::CountActiveValidatorsInNetworkResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! count_active_validators_in_network_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl CountActiveValidatorsInNetworkHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::CountActiveValidatorsInNetworkPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::CountActiveValidatorsInNetworkResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(count_active_validators_in_network_handler); + +/// GET /api/v4/{network}/validators/countActiveValidators service +struct CountActiveValidatorsInNetworkService +where + H: CountActiveValidatorsInNetworkHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for CountActiveValidatorsInNetworkService +where + H: CountActiveValidatorsInNetworkHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl CountActiveValidatorsInNetworkService +where + H: CountActiveValidatorsInNetworkHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for CountActiveValidatorsInNetworkService +where + H: CountActiveValidatorsInNetworkHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( CountActiveValidatorsInNetworkHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/validators/owned_by/{ownerAddress}/cost handler +pub trait ValidatorsV4ControllerCostHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ValidatorsV4ControllerCostHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ValidatorsV4ControllerCostPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::ValidatorsV4ControllerCostResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! validators_v4_controller_cost_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ValidatorsV4ControllerCostHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ValidatorsV4ControllerCostPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::ValidatorsV4ControllerCostResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(validators_v4_controller_cost_handler); + +/// GET /api/v4/{network}/validators/owned_by/{ownerAddress}/cost service +struct ValidatorsV4ControllerCostService +where + H: ValidatorsV4ControllerCostHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ValidatorsV4ControllerCostService +where + H: ValidatorsV4ControllerCostHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ValidatorsV4ControllerCostService +where + H: ValidatorsV4ControllerCostHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ValidatorsV4ControllerCostService +where + H: ValidatorsV4ControllerCostHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ValidatorsV4ControllerCostHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/validators/in_operator/{operator} handler +pub trait ValidatorsV4ControllerInOperatorHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ValidatorsV4ControllerInOperatorHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ValidatorsV4ControllerInOperatorPath,super::endpoint::ValidatorsV4ControllerInOperatorQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::ValidatorsV4ControllerInOperatorResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! validators_v4_controller_in_operator_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ValidatorsV4ControllerInOperatorHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ValidatorsV4ControllerInOperatorPath,super::endpoint::ValidatorsV4ControllerInOperatorQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::ValidatorsV4ControllerInOperatorResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(validators_v4_controller_in_operator_handler); + +/// GET /api/v4/{network}/validators/in_operator/{operator} service +struct ValidatorsV4ControllerInOperatorService +where + H: ValidatorsV4ControllerInOperatorHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ValidatorsV4ControllerInOperatorService +where + H: ValidatorsV4ControllerInOperatorHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ValidatorsV4ControllerInOperatorService +where + H: ValidatorsV4ControllerInOperatorHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ValidatorsV4ControllerInOperatorService +where + H: ValidatorsV4ControllerInOperatorHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ValidatorsV4ControllerInOperatorHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/validators/incentivized/{validator} handler +pub trait ValidatorsV4ControllerIncentivizedHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ValidatorsV4ControllerIncentivizedHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ValidatorsV4ControllerIncentivizedPath,super::endpoint::ValidatorsV4ControllerIncentivizedQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::ValidatorsV4ControllerIncentivizedResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! validators_v4_controller_incentivized_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ValidatorsV4ControllerIncentivizedHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ValidatorsV4ControllerIncentivizedPath,super::endpoint::ValidatorsV4ControllerIncentivizedQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::ValidatorsV4ControllerIncentivizedResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(validators_v4_controller_incentivized_handler); + +/// GET /api/v4/{network}/validators/incentivized/{validator} service +struct ValidatorsV4ControllerIncentivizedService +where + H: ValidatorsV4ControllerIncentivizedHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ValidatorsV4ControllerIncentivizedService +where + H: ValidatorsV4ControllerIncentivizedHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ValidatorsV4ControllerIncentivizedService +where + H: ValidatorsV4ControllerIncentivizedHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ValidatorsV4ControllerIncentivizedService +where + H: ValidatorsV4ControllerIncentivizedHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ValidatorsV4ControllerIncentivizedHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/validators/{validator} handler +pub trait ValidatorsV4ControllerValidatorHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ValidatorsV4ControllerValidatorHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ValidatorsV4ControllerValidatorPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::ValidatorsV4ControllerValidatorResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! validators_v4_controller_validator_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ValidatorsV4ControllerValidatorHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ValidatorsV4ControllerValidatorPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::ValidatorsV4ControllerValidatorResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(validators_v4_controller_validator_handler); + +/// GET /api/v4/{network}/validators/{validator} service +struct ValidatorsV4ControllerValidatorService +where + H: ValidatorsV4ControllerValidatorHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ValidatorsV4ControllerValidatorService +where + H: ValidatorsV4ControllerValidatorHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ValidatorsV4ControllerValidatorService +where + H: ValidatorsV4ControllerValidatorHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ValidatorsV4ControllerValidatorService +where + H: ValidatorsV4ControllerValidatorHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ValidatorsV4ControllerValidatorHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/validators/isRegisteredValidator/{validator} handler +pub trait ValidatorsV4ControllerIsRegisteredValidatorHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ValidatorsV4ControllerIsRegisteredValidatorHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ValidatorsV4ControllerIsRegisteredValidatorPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::ValidatorsV4ControllerIsRegisteredValidatorResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! validators_v4_controller_is_registered_validator_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ValidatorsV4ControllerIsRegisteredValidatorHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ValidatorsV4ControllerIsRegisteredValidatorPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::ValidatorsV4ControllerIsRegisteredValidatorResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(validators_v4_controller_is_registered_validator_handler); + +/// GET /api/v4/{network}/validators/isRegisteredValidator/{validator} service +struct ValidatorsV4ControllerIsRegisteredValidatorService +where + H: ValidatorsV4ControllerIsRegisteredValidatorHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ValidatorsV4ControllerIsRegisteredValidatorService +where + H: ValidatorsV4ControllerIsRegisteredValidatorHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ValidatorsV4ControllerIsRegisteredValidatorService +where + H: ValidatorsV4ControllerIsRegisteredValidatorHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ValidatorsV4ControllerIsRegisteredValidatorService +where + H: ValidatorsV4ControllerIsRegisteredValidatorHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ValidatorsV4ControllerIsRegisteredValidatorHandler::call(handler, req, state).await) + }) + } +} + + +/// POST /api/v4/{network}/validators/registeredByPublicKeys handler +pub trait ApiV4ValidatorRegisteredByPublicKeyCreateHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ApiV4ValidatorRegisteredByPublicKeyCreateHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ApiV4ValidatorRegisteredByPublicKeyCreatePath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::ApiV4ValidatorRegisteredByPublicKeyCreateResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! api_v4_validator_registered_by_public_key_create_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ApiV4ValidatorRegisteredByPublicKeyCreateHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ApiV4ValidatorRegisteredByPublicKeyCreatePath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::ApiV4ValidatorRegisteredByPublicKeyCreateResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(api_v4_validator_registered_by_public_key_create_handler); + +/// POST /api/v4/{network}/validators/registeredByPublicKeys service +struct ApiV4ValidatorRegisteredByPublicKeyCreateService +where + H: ApiV4ValidatorRegisteredByPublicKeyCreateHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ApiV4ValidatorRegisteredByPublicKeyCreateService +where + H: ApiV4ValidatorRegisteredByPublicKeyCreateHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ApiV4ValidatorRegisteredByPublicKeyCreateService +where + H: ApiV4ValidatorRegisteredByPublicKeyCreateHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ApiV4ValidatorRegisteredByPublicKeyCreateService +where + H: ApiV4ValidatorRegisteredByPublicKeyCreateHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ApiV4ValidatorRegisteredByPublicKeyCreateHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/validators handler +pub trait ValidatorsV4ControllerValidatorsHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ValidatorsV4ControllerValidatorsHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ValidatorsV4ControllerValidatorsPath,super::endpoint::ValidatorsV4ControllerValidatorsQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::ValidatorsV4ControllerValidatorsResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! validators_v4_controller_validators_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ValidatorsV4ControllerValidatorsHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ValidatorsV4ControllerValidatorsPath,super::endpoint::ValidatorsV4ControllerValidatorsQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::ValidatorsV4ControllerValidatorsResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(validators_v4_controller_validators_handler); + +/// GET /api/v4/{network}/validators service +struct ValidatorsV4ControllerValidatorsService +where + H: ValidatorsV4ControllerValidatorsHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ValidatorsV4ControllerValidatorsService +where + H: ValidatorsV4ControllerValidatorsHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ValidatorsV4ControllerValidatorsService +where + H: ValidatorsV4ControllerValidatorsHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ValidatorsV4ControllerValidatorsService +where + H: ValidatorsV4ControllerValidatorsHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ValidatorsV4ControllerValidatorsHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/validators/duty_counts/{from_epoch}/{to_epoch} handler +pub trait ValidatorsV4ControllerDutyCountsHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ValidatorsV4ControllerDutyCountsHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ValidatorsV4ControllerDutyCountsPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::ValidatorsV4ControllerDutyCountsResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! validators_v4_controller_duty_counts_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ValidatorsV4ControllerDutyCountsHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ValidatorsV4ControllerDutyCountsPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::ValidatorsV4ControllerDutyCountsResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(validators_v4_controller_duty_counts_handler); + +/// GET /api/v4/{network}/validators/duty_counts/{from_epoch}/{to_epoch} service +struct ValidatorsV4ControllerDutyCountsService +where + H: ValidatorsV4ControllerDutyCountsHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ValidatorsV4ControllerDutyCountsService +where + H: ValidatorsV4ControllerDutyCountsHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ValidatorsV4ControllerDutyCountsService +where + H: ValidatorsV4ControllerDutyCountsHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ValidatorsV4ControllerDutyCountsService +where + H: ValidatorsV4ControllerDutyCountsHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ValidatorsV4ControllerDutyCountsHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/validators/validatorsByClusterHash/{clusterHash} handler +pub trait ApiV4ValidatorsValidatorsByClusterHashGetHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ApiV4ValidatorsValidatorsByClusterHashGetHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ApiV4ValidatorsValidatorsByClusterHashGetPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::ApiV4ValidatorsValidatorsByClusterHashGetResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! api_v4_validators_validators_by_cluster_hash_get_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ApiV4ValidatorsValidatorsByClusterHashGetHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ApiV4ValidatorsValidatorsByClusterHashGetPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::ApiV4ValidatorsValidatorsByClusterHashGetResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(api_v4_validators_validators_by_cluster_hash_get_handler); + +/// GET /api/v4/{network}/validators/validatorsByClusterHash/{clusterHash} service +struct ApiV4ValidatorsValidatorsByClusterHashGetService +where + H: ApiV4ValidatorsValidatorsByClusterHashGetHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ApiV4ValidatorsValidatorsByClusterHashGetService +where + H: ApiV4ValidatorsValidatorsByClusterHashGetHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ApiV4ValidatorsValidatorsByClusterHashGetService +where + H: ApiV4ValidatorsValidatorsByClusterHashGetHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ApiV4ValidatorsValidatorsByClusterHashGetService +where + H: ApiV4ValidatorsValidatorsByClusterHashGetHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ApiV4ValidatorsValidatorsByClusterHashGetHandler::call(handler, req, state).await) + }) + } +} + + +/// POST /api/v4/{network}/validators/validatorsWithdrawCredentials handler +pub trait ApiV4ValidatorValidatorsWithdrawCredentialCreateHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl ApiV4ValidatorValidatorsWithdrawCredentialCreateHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::ApiV4ValidatorValidatorsWithdrawCredentialCreatePath,super::model::ApiV4ValidatorValidatorsWithdrawCredentialCreateRequestBody,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, ).await; + + let response: super::endpoint::ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! api_v4_validator_validators_withdraw_credential_create_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl ApiV4ValidatorValidatorsWithdrawCredentialCreateHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::ApiV4ValidatorValidatorsWithdrawCredentialCreatePath,super::model::ApiV4ValidatorValidatorsWithdrawCredentialCreateRequestBody,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into,B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + let req = Request::from_parts(parts, body);let body = match axum::Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + let res = self(path.0, body.0, $($ty,)*).await; + + let response: super::endpoint::ApiV4ValidatorValidatorsWithdrawCredentialCreateResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(api_v4_validator_validators_withdraw_credential_create_handler); + +/// POST /api/v4/{network}/validators/validatorsWithdrawCredentials service +struct ApiV4ValidatorValidatorsWithdrawCredentialCreateService +where + H: ApiV4ValidatorValidatorsWithdrawCredentialCreateHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for ApiV4ValidatorValidatorsWithdrawCredentialCreateService +where + H: ApiV4ValidatorValidatorsWithdrawCredentialCreateHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl ApiV4ValidatorValidatorsWithdrawCredentialCreateService +where + H: ApiV4ValidatorValidatorsWithdrawCredentialCreateHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for ApiV4ValidatorValidatorsWithdrawCredentialCreateService +where + H: ApiV4ValidatorValidatorsWithdrawCredentialCreateHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( ApiV4ValidatorValidatorsWithdrawCredentialCreateHandler::call(handler, req, state).await) + }) + } +} + + + +/// V4 router +pub struct V4Router { + pub(crate) router: Router, +} + +impl V4Router where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + /// GET /api/v4/{network}/accounts + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::AccountV4ControllerListPath,super::endpoint::AccountV4ControllerListQuery) -> AccountV4ControllerListResponse { + /// todo!(); + /// } + /// let router = V4Router::default().account_v4_controller_list(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::AccountV4ControllerListPath,super::endpoint::AccountV4ControllerListQuery, ...extractors) -> AccountV4ControllerListResponse { + /// todo!(); + /// } + /// let router = V4Router::default().account_v4_controller_list(handler); + /// ``` + pub fn account_v4_controller_list(mut self, handler: H) -> Self + where + H: AccountV4ControllerListHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/accounts", on_service(MethodFilter::GET, AccountV4ControllerListService::new(handler))); + self + } + + /// GET /api/v4/{network}/accounts/{ownerAddress} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::AccountV4ControllerByIdPath) -> AccountV4ControllerByIdResponse { + /// todo!(); + /// } + /// let router = V4Router::default().account_v4_controller_by_id(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::AccountV4ControllerByIdPath, ...extractors) -> AccountV4ControllerByIdResponse { + /// todo!(); + /// } + /// let router = V4Router::default().account_v4_controller_by_id(handler); + /// ``` + pub fn account_v4_controller_by_id(mut self, handler: H) -> Self + where + H: AccountV4ControllerByIdHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/accounts/:ownerAddress", on_service(MethodFilter::GET, AccountV4ControllerByIdService::new(handler))); + self + } + + /// GET /api/v4/{network}/duties/{validator} + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::DutiesV4ControllerDutiesPath,super::endpoint::DutiesV4ControllerDutiesQuery) -> DutiesV4ControllerDutiesResponse { + /// todo!(); + /// } + /// let router = V4Router::default().duties_v4_controller_duties(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::DutiesV4ControllerDutiesPath,super::endpoint::DutiesV4ControllerDutiesQuery, ...extractors) -> DutiesV4ControllerDutiesResponse { + /// todo!(); + /// } + /// let router = V4Router::default().duties_v4_controller_duties(handler); + /// ``` + pub fn duties_v4_controller_duties(mut self, handler: H) -> Self + where + H: DutiesV4ControllerDutiesHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/duties/:validator", on_service(MethodFilter::GET, DutiesV4ControllerDutiesService::new(handler))); + self + } + + /// GET /api/v4/{network}/health + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::HealthV4ControllerHealthPath) -> HealthV4ControllerHealthResponse { + /// todo!(); + /// } + /// let router = V4Router::default().health_v4_controller_health(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::HealthV4ControllerHealthPath, ...extractors) -> HealthV4ControllerHealthResponse { + /// todo!(); + /// } + /// let router = V4Router::default().health_v4_controller_health(handler); + /// ``` + pub fn health_v4_controller_health(mut self, handler: H) -> Self + where + H: HealthV4ControllerHealthHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/health", on_service(MethodFilter::GET, HealthV4ControllerHealthService::new(handler))); + self + } + + /// GET /api/v4/{network}/incentivization/merkle-tree + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionPath) -> IncentivizationV4ControllerMigrationOperatorsDistributionResponse { + /// todo!(); + /// } + /// let router = V4Router::default().incentivization_v4_controller_migration_operators_distribution(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionPath, ...extractors) -> IncentivizationV4ControllerMigrationOperatorsDistributionResponse { + /// todo!(); + /// } + /// let router = V4Router::default().incentivization_v4_controller_migration_operators_distribution(handler); + /// ``` + pub fn incentivization_v4_controller_migration_operators_distribution(mut self, handler: H) -> Self + where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/incentivization/merkle-tree", on_service(MethodFilter::GET, IncentivizationV4ControllerMigrationOperatorsDistributionService::new(handler))); + self + } + + /// GET /api/v4/{network}/search + /// + /// # Examples + /// + /// ``` + /// async fn handler(super::endpoint::SearchV4ControllerSearchPath,super::endpoint::SearchV4ControllerSearchQuery) -> SearchV4ControllerSearchResponse { + /// todo!(); + /// } + /// let router = V4Router::default().search_v4_controller_search(handler); + /// ``` + /// + /// ``` + /// async fn handler(super::endpoint::SearchV4ControllerSearchPath,super::endpoint::SearchV4ControllerSearchQuery, ...extractors) -> SearchV4ControllerSearchResponse { + /// todo!(); + /// } + /// let router = V4Router::default().search_v4_controller_search(handler); + /// ``` + pub fn search_v4_controller_search(mut self, handler: H) -> Self + where + H: SearchV4ControllerSearchHandler, + T: 'static + { + self.router = self.router.route("/api/v4/:network/search", on_service(MethodFilter::GET, SearchV4ControllerSearchService::new(handler))); + self + } +} + +impl Default for V4Router where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From> for Router { + fn from(r: V4Router) -> Self { + r.router + } +} + +/// GET /api/v4/{network}/accounts handler +pub trait AccountV4ControllerListHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl AccountV4ControllerListHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::AccountV4ControllerListPath,super::endpoint::AccountV4ControllerListQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::AccountV4ControllerListResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! account_v4_controller_list_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl AccountV4ControllerListHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::AccountV4ControllerListPath,super::endpoint::AccountV4ControllerListQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::AccountV4ControllerListResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(account_v4_controller_list_handler); + +/// GET /api/v4/{network}/accounts service +struct AccountV4ControllerListService +where + H: AccountV4ControllerListHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for AccountV4ControllerListService +where + H: AccountV4ControllerListHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl AccountV4ControllerListService +where + H: AccountV4ControllerListHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for AccountV4ControllerListService +where + H: AccountV4ControllerListHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( AccountV4ControllerListHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/accounts/{ownerAddress} handler +pub trait AccountV4ControllerByIdHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl AccountV4ControllerByIdHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::AccountV4ControllerByIdPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::AccountV4ControllerByIdResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! account_v4_controller_by_id_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl AccountV4ControllerByIdHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::AccountV4ControllerByIdPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::AccountV4ControllerByIdResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(account_v4_controller_by_id_handler); + +/// GET /api/v4/{network}/accounts/{ownerAddress} service +struct AccountV4ControllerByIdService +where + H: AccountV4ControllerByIdHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for AccountV4ControllerByIdService +where + H: AccountV4ControllerByIdHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl AccountV4ControllerByIdService +where + H: AccountV4ControllerByIdHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for AccountV4ControllerByIdService +where + H: AccountV4ControllerByIdHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( AccountV4ControllerByIdHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/duties/{validator} handler +pub trait DutiesV4ControllerDutiesHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl DutiesV4ControllerDutiesHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::DutiesV4ControllerDutiesPath,super::endpoint::DutiesV4ControllerDutiesQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::DutiesV4ControllerDutiesResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! duties_v4_controller_duties_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl DutiesV4ControllerDutiesHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::DutiesV4ControllerDutiesPath,super::endpoint::DutiesV4ControllerDutiesQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::DutiesV4ControllerDutiesResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(duties_v4_controller_duties_handler); + +/// GET /api/v4/{network}/duties/{validator} service +struct DutiesV4ControllerDutiesService +where + H: DutiesV4ControllerDutiesHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for DutiesV4ControllerDutiesService +where + H: DutiesV4ControllerDutiesHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl DutiesV4ControllerDutiesService +where + H: DutiesV4ControllerDutiesHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for DutiesV4ControllerDutiesService +where + H: DutiesV4ControllerDutiesHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( DutiesV4ControllerDutiesHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/health handler +pub trait HealthV4ControllerHealthHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl HealthV4ControllerHealthHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::HealthV4ControllerHealthPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::HealthV4ControllerHealthResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! health_v4_controller_health_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl HealthV4ControllerHealthHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::HealthV4ControllerHealthPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::HealthV4ControllerHealthResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(health_v4_controller_health_handler); + +/// GET /api/v4/{network}/health service +struct HealthV4ControllerHealthService +where + H: HealthV4ControllerHealthHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for HealthV4ControllerHealthService +where + H: HealthV4ControllerHealthHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl HealthV4ControllerHealthService +where + H: HealthV4ControllerHealthHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for HealthV4ControllerHealthService +where + H: HealthV4ControllerHealthHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( HealthV4ControllerHealthHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/incentivization/merkle-tree handler +pub trait IncentivizationV4ControllerMigrationOperatorsDistributionHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl IncentivizationV4ControllerMigrationOperatorsDistributionHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionPath,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, ).await; + + let response: super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! incentivization_v4_controller_migration_operators_distribution_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl IncentivizationV4ControllerMigrationOperatorsDistributionHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionPath,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, $($ty,)*).await; + + let response: super::endpoint::IncentivizationV4ControllerMigrationOperatorsDistributionResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(incentivization_v4_controller_migration_operators_distribution_handler); + +/// GET /api/v4/{network}/incentivization/merkle-tree service +struct IncentivizationV4ControllerMigrationOperatorsDistributionService +where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for IncentivizationV4ControllerMigrationOperatorsDistributionService +where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl IncentivizationV4ControllerMigrationOperatorsDistributionService +where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for IncentivizationV4ControllerMigrationOperatorsDistributionService +where + H: IncentivizationV4ControllerMigrationOperatorsDistributionHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( IncentivizationV4ControllerMigrationOperatorsDistributionHandler::call(handler, req, state).await) + }) + } +} + + +/// GET /api/v4/{network}/search handler +pub trait SearchV4ControllerSearchHandler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl SearchV4ControllerSearchHandler<(), S, B> for F +where + F: FnOnce(super::endpoint::SearchV4ControllerSearchPath,super::endpoint::SearchV4ControllerSearchQuery,) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + + B: Send + 'static, + + S: Send + Sync + 'static, +{fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + + let res = self(path.0, query.0, ).await; + + let response: super::endpoint::SearchV4ControllerSearchResponse = res.into(); + + response.into() + }) + } +} + +macro_rules! search_v4_controller_search_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl SearchV4ControllerSearchHandler<($($ty,)*), S, B> for F + where + F: FnOnce(super::endpoint::SearchV4ControllerSearchPath,super::endpoint::SearchV4ControllerSearchQuery,$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + B: Send + 'static, + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + + let path = match axum::extract::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + let query = match axum::extract::Query::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + + + let res = self(path.0, query.0, $($ty,)*).await; + + let response: super::endpoint::SearchV4ControllerSearchResponse = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!(search_v4_controller_search_handler); + +/// GET /api/v4/{network}/search service +struct SearchV4ControllerSearchService +where + H: SearchV4ControllerSearchHandler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for SearchV4ControllerSearchService +where + H: SearchV4ControllerSearchHandler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl SearchV4ControllerSearchService +where + H: SearchV4ControllerSearchHandler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for SearchV4ControllerSearchService +where + H: SearchV4ControllerSearchHandler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( SearchV4ControllerSearchHandler::call(handler, req, state).await) + }) + } +} + + diff --git a/anchor/http_api/openapi.json b/anchor/http_api/openapi.json new file mode 100644 index 000000000..9cac13fbf --- /dev/null +++ b/anchor/http_api/openapi.json @@ -0,0 +1,2281 @@ + { + "openapi": "3.0.0", + "paths": { + "/api/v4/{network}/accounts": { + "get": { + "operationId": "AccountV4Controller_list", + "summary": "List accounts with pagination", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Accounts found and returned in response" + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Accounts", + "v4" + ] + } + }, + "/api/v4/{network}/accounts/{ownerAddress}": { + "get": { + "operationId": "AccountV4Controller_byId", + "summary": "Get fee recipient by owner address", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "ownerAddress", + "required": true, + "in": "path", + "description": "Owner address of account", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Account found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Accounts", + "v4" + ] + } + }, + "/api/v4/{network}/accounts/counts/{ownerAddress}": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + }, + { + "name": "ownerAddress", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Owner address" + } + ], + "get": { + "summary": "Get operators and clusters count by owner address", + "tags": [ + "Accounts" + ], + "responses": { + "200": { + "description": "Counts found and returned in response" + }, + "400": { + "description": "Owner address has wrong format" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/v4/{network}/clusters/count": { + "get": { + "operationId": "ClusterV4Controller_count", + "summary": "Count clusters in network", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Clusters counted and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters": { + "get": { + "operationId": "ClusterV4Controller_list", + "summary": "List clusters with pagination", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "from", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "limit", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "operatorDetails", + "required": false, + "in": "query", + "description": "Response with operators details", + "schema": { + "oneOf": [ + { + "type": "boolean" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Clusters found and returned in response" + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/updates": { + "get": { + "operationId": "ClusterV4Controller_updates", + "summary": "Get clusters updates from specific block number", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "fromBlock", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Cluster updates found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/{id}": { + "get": { + "operationId": "ClusterV4Controller_byId", + "summary": "Get cluster by its primary ID or keccak256 hash", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "description": "Cluster keccak256 hash ID or primary numeric ID", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "operatorDetails", + "required": false, + "in": "query", + "description": "Response with operator details", + "schema": { + "oneOf": [ + { + "type": "boolean" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Cluster found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/owner/{owner}/operators/{operators}": { + "get": { + "operationId": "ClusterV4Controller_byOwnerAndOperators", + "summary": "Get cluster by owner address and operators list", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "owner", + "required": true, + "in": "path", + "description": "Owner address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "operators", + "required": true, + "in": "path", + "description": "Comma-separated operator IDs", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "operatorDetails", + "required": false, + "in": "query", + "description": "Response with operators details", + "schema": { + "oneOf": [ + { + "type": "boolean" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Cluster found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/owner/{owner}": { + "get": { + "operationId": "ClusterV4Controller_byOwner", + "summary": "Get clusters by owner address", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Sort by one or few fields.

You can sort only by:   id,  index,  validator_count

Examples:
  1. id:asc,index:desc

  2. validator_count:desc

  3. without specifying sort order: validator_count,id - equals to: validator_count:asc,id:asc

", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "operatorDetails", + "required": false, + "in": "query", + "description": "Response with operators details", + "schema": { + "oneOf": [ + { + "type": "boolean" + } + ] + } + }, + { + "name": "owner", + "required": true, + "in": "path", + "description": "Owner address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Clusters found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/hash/{clusterHash}": { + "get": { + "operationId": "ClusterV4Controller_validators", + "summary": "Get cluster info (validators and operators) by cluster hash", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "clusterHash", + "required": true, + "in": "path", + "description": "Cluster hash", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Cluster info found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/duties/{validator}": { + "get": { + "operationId": "DutiesV4Controller_duties", + "summary": "List of duties performed by validator", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "validator", + "required": true, + "in": "path", + "description": "Validator address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validator found and duties returned in response" + }, + "400": { + "description": "Validator address has wrong format" + }, + "404": { + "description": "Validator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Duties", + "v4", + "Duties" + ] + } + }, + "/api/v4/{network}/events/{txHash}": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + }, + { + "name": "txHash", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Transaction hash" + } + ], + "get": { + "summary": "Get event by transaction hash", + "tags": [ + "Events" + ], + "responses": { + "200": { + "description": "Event found and returned in response" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/v4/{network}/faucet": { + "get": { + "operationId": "FaucetController_getTransactions", + "summary": "Get transactions by owner address or without", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Faucet" + ] + }, + "post": { + "operationId": "FaucetController_setTransaction", + "summary": "Create transaction by owner address", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ownerAddress", + "network", + "version" + ], + "properties": { + "owner_address": { + "type": "string" + }, + "networkId": { + "type": "number" + }, + "version": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "One or more parameters are invalid" + }, + "406": { + "description": "Reached max transactions per day or faucet depleted" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Faucet" + ] + } + }, + "/api/v4/{network}/faucet/config": { + "get": { + "operationId": "FaucetController_getFaucetConfig", + "summary": "Get transactions config", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Faucet" + ] + } + }, + "/api/finance/currency/convert/{symbol}/{quote}": { + "get": { + "operationId": "FinanceController_currencyConvert", + "summary": "Convert from a currency into a quote currency", + "parameters": [ + { + "name": "symbol", + "required": true, + "in": "path", + "description": "Currency to convert from", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "quote", + "required": true, + "in": "path", + "description": "Currency to convert to", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Both currencies are valid and has been converted", + "content": { + "application/json": { + "schema": { + "properties": { + "symbol": { + "type": "string" + }, + "quote": { + "type": "string" + }, + "price": { + "type": "number" + } + } + } + } + } + }, + "404": { + "description": "Currency can not be found or is not valid", + "content": { + "application/json": { + "schema": { + "properties": { + "symbol": { + "type": "string" + }, + "quote": { + "type": "string" + }, + "error": { + "type": "string" + } + } + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Finance" + ] + } + }, + "/api/v4/{network}/health": { + "get": { + "operationId": "HealthV4Controller_health", + "summary": "Health check", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Health check for all endpoints" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Health", + "v4" + ] + } + }, + "/api/v4/{network}/incentivization/merkle-tree": { + "get": { + "operationId": "IncentivizationV4Controller_migrationOperatorsDistribution", + "summary": "Merkle tree for version and network", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Merkle tree found for this version and network" + } + }, + "tags": [ + "Incentivized", + "v4", + "Incentivized" + ] + } + }, + "/api/v4/{network}/operators/graph": { + "get": { + "operationId": "OperatorsV4Controller_graph", + "summary": "List of operators and validators for search widget", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 10000", + "schema": { + "minimum": 1, + "maximum": 10000, + "default": 1000, + "type": "number" + } + }, + { + "name": "randomize", + "required": false, + "in": "query", + "description": "To use this parameter specify \"true\" as string value", + "schema": { + "default": "", + "enum": [ + "true", + "false", + "" + ], + "type": "string" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Operators found and returned in response" + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators", + "Graph" + ] + } + }, + "/api/v4/{network}/operators/owned_by/{ownerAddress}": { + "get": { + "operationId": "OperatorsV4Controller_ownedBy", + "summary": "List of operators by owner address", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Sort by one or few fields.

You can sort only by:   id,  fee,  public_key,  owner_address,  name,  address,  location,  setup_provider,  eth1_node_client,  eth2_node_client,  description,  website_url,  twitter_url,  linkedin_url,  validators_count,  status,  performance.30d,  performance.24h,  type

Examples:
  1. name:asc,address:desc

  2. validators_count:desc

  3. without specifying sort order: validators_count,name:asc - equals to: validators_count:asc,name:asc

", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "ownerAddress", + "required": true, + "in": "path", + "description": "Owner address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Operators found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/incentivized/{operator}": { + "get": { + "operationId": "OperatorsV4Controller_incentivized", + "summary": "Incentivized stats for operator", + "parameters": [ + { + "name": "epochFrom", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "epochsPerRound", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "rounds", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 5, + "default": 3, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "operator", + "required": true, + "in": "path", + "description": "Operator address or ID from the contract", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Operator found and returned in response" + }, + "400": { + "description": "Operator address has wrong format" + }, + "404": { + "description": "Operator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/{operator}": { + "get": { + "operationId": "OperatorsV4Controller_getOperator", + "summary": "Single operator data", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "operator", + "required": true, + "in": "path", + "description": "Operator address or ID from the contract", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Operator found and returned in response" + }, + "400": { + "description": "Operator id/address has wrong format" + }, + "404": { + "description": "Operator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/dkg_health_check": { + "post": { + "operationId": "OperatorsV4Controller_getDkgHealthCheck", + "summary": "Dkg address health check", + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DkgHealthCheckDto" + } + } + } + }, + "responses": { + "200": { + "description": "true if dkg endpoint is active, false else" + }, + "201": { + "description": "true if dkg endpoint is active, false else" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/public_key/{public_key}": { + "get": { + "operationId": "OperatorsV4Controller_getByPublicKey", + "summary": "Get operator by public key", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "public_key", + "required": true, + "in": "path", + "description": "Operator by public key", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Operator found and returned in response" + }, + "400": { + "description": "Operator public key has wrong format" + }, + "404": { + "description": "Operator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators": { + "get": { + "operationId": "OperatorsV4Controller_operators", + "summary": "List of operators", + "parameters": [ + { + "name": "type", + "required": false, + "in": "query", + "description": "Case-sensitive filter by operator \"type\" in full match manner, comma-separated for multiple matching.

Example:verified_operator, verified_operator,dapp_node, ", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 5000", + "schema": { + "minimum": 1, + "maximum": 5000, + "default": 10, + "type": "number" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Sort by one or few fields.

You can sort only by:   id,  fee,  public_key,  owner_address,  name,  address,  location,  setup_provider,  eth1_node_client,  eth2_node_client,  description,  website_url,  twitter_url,  linkedin_url,  validators_count,  status,  performance.30d,  performance.24h,  type

Examples:
  1. name:asc,address:desc

  2. validators_count:desc

  3. without specifying sort order: validators_count,name:asc - equals to: validators_count:asc,name:asc

", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Full-text search for entries matching all fields in a case-insensitive way", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "has_dkg_address", + "required": false, + "in": "query", + "description": "Filter operators by whether they have a DKG address or not.", + "schema": { + "type": "boolean" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Operators found and returned in response" + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + }, + "post": { + "operationId": "OperatorsV4Controller_getByIds", + "summary": "List operators by ids", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ids" + ], + "properties": { + "ids": { + "type": "array", + "items": { + "type": "number" + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/{operator}/metadata": { + "put": { + "operationId": "OperatorsV4Controller_updateMetadata", + "summary": "Update operator metadata", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "operator", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperatorMetadataDto" + } + } + } + }, + "responses": { + "200": { + "description": "Operator found and his metadata was updated. Final operator returned in response" + }, + "401": { + "description": "Owner address is not authorized to perform this action" + }, + "404": { + "description": "Operator does not exist" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/nodes/{layer}": { + "get": { + "operationId": "OperatorsV4Controller_nodes", + "summary": "List of available Eth node clients", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "layer", + "required": true, + "in": "path", + "description": "Eth node layer", + "schema": { + "oneOf": [ + { + "type": "string" + } + ], + "enum": [ + "1", + "2" + ] + } + } + ], + "responses": { + "200": { + "description": "List of available Eth node clients" + }, + "400": { + "description": "Layer has wrong format or value" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/locations": { + "get": { + "operationId": "OperatorsV4Controller_locations", + "summary": "List of available locations", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of available locations" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/search": { + "get": { + "operationId": "SearchV4Controller_search", + "summary": "Search operators and validators", + "parameters": [ + { + "name": "search", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "searchFor", + "required": false, + "in": "query", + "schema": { + "default": "both", + "enum": [ + "operators", + "validators", + "both" + ], + "type": "string" + } + }, + { + "name": "operatorsLimit", + "required": false, + "in": "query", + "schema": { + "minimum": 0, + "default": 5, + "type": "number" + } + }, + { + "name": "validatorsLimit", + "required": false, + "in": "query", + "schema": { + "minimum": 0, + "default": 5, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Operators or validators found and returned in response" + }, + "400": { + "description": "Search parameters provided with incorrect values" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Search", + "v4" + ] + } + }, + "/api/v4/{network}/validators/countActiveValidators": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + } + ], + "get": { + "summary": "Count active validators in network", + "tags": [ + "Validators" + ], + "responses": { + "200": { + "description": "Validators counted and returned in response" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/v4/{network}/validators/owned_by/{ownerAddress}/cost": { + "get": { + "operationId": "ValidatorsV4Controller_cost", + "summary": "Cost of all validators depending on in which operators they are.", + "parameters": [ + { + "name": "ownerAddress", + "required": true, + "in": "path", + "description": "Owner address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Account address has wrong format" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/in_operator/{operator}": { + "get": { + "operationId": "ValidatorsV4Controller_inOperator", + "summary": "List of validators in operator", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "operator", + "required": true, + "in": "path", + "description": "Operator address or ID from the contract", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validators found and returned in response" + }, + "404": { + "description": "No such operator or operator does not have validators" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/incentivized/{validator}": { + "get": { + "operationId": "ValidatorsV4Controller_incentivized", + "summary": "Incentivized stats", + "parameters": [ + { + "name": "epochFrom", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "epochsPerRound", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "rounds", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 5, + "default": 3, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "validator", + "required": true, + "in": "path", + "description": "Validator address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validator found and returned in response" + }, + "400": { + "description": "Validator address has wrong format" + }, + "404": { + "description": "Validator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/{validator}": { + "get": { + "operationId": "ValidatorsV4Controller_validator", + "summary": "Single validator data", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "validator", + "required": true, + "in": "path", + "description": "Validator public_key", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validator found and returned in response" + }, + "400": { + "description": "Validator public_key has wrong format" + }, + "404": { + "description": "Validator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/isRegisteredValidator/{validator}": { + "get": { + "operationId": "ValidatorsV4Controller_validator", + "summary": "If validator is registered - single validator data, 404 otherwise", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "validator", + "required": true, + "in": "path", + "description": "Validator public_key", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validator found and returned in response" + }, + "400": { + "description": "Validator public_key has wrong format" + }, + "404": { + "description": "Validator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/registeredByPublicKeys": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + } + ], + "post": { + "summary": "Return registered public keys", + "tags": [ + "Validators" + ], + "responses": { + "200": { + "description": "Validators found and returned in response" + }, + "400": { + "description": "Public key has wrong format" + }, + "500": { + "description": "Internal server error" + } + }, + "requestBody": { + "description": "Public keys", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "publicKeys": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of public keys" + } + }, + "required": [ + "publicKeys" + ] + } + } + }, + "components": { + "schemas": { + "RegisteredByPublicKeysDto": { + "type": "object", + "properties": { + "publicKeys": { + "type": "string[]" + } + } + } + } + } + } + } + }, + "/api/v4/{network}/validators": { + "get": { + "operationId": "ValidatorsV4Controller_validators", + "summary": "List of validators", + "parameters": [ + { + "name": "lastId", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "pageDirection", + "required": false, + "in": "query", + "description": "either \"next\" or \"prev\"", + "schema": { + "type": "string" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 1000", + "schema": { + "minimum": 1, + "maximum": 1000, + "default": 10, + "type": "number" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Sort by one or few fields.

You can sort only by:   id,  status,  public_key,  owner_address

Examples:
  1. id:asc,public_key:desc

  2. public_key

  3. without specifying sort order: owner_address,public_key - equals to: owner_address:asc,public_key:asc

", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "ownerAddress", + "required": false, + "in": "query", + "description": "Filter by owner", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Full-text search for entries matching all fields in a case-insensitive way", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Validators found and returned in response" + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/duty_counts/{from_epoch}/{to_epoch}": { + "get": { + "operationId": "ValidatorsV4Controller_dutyCounts", + "summary": "Duty counts by validators in an epoch range", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "from_epoch", + "required": true, + "in": "path", + "description": "Epoch number", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "to_epoch", + "required": true, + "in": "path", + "description": "Epoch number", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Duty counts found and returned in response" + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/validatorsByClusterHash/{clusterHash}": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + }, + { + "name": "clusterHash", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Cluster hash" + } + ], + "get": { + "summary": "Return validator public keys list by cluster hash", + "tags": [ + "Validators" + ], + "responses": { + "200": { + "description": "Validators found and returned in response" + }, + "400": { + "description": "Cluster hash has wrong format" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/v4/{network}/validators/validatorsWithdrawCredentials": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + } + ], + "post": { + "summary": "Return withdraw credentials", + "tags": [ + "Validators" + ], + "responses": { + "200": { + "description": "Withdraw credentials found and returned in response" + }, + "400": { + "description": "Public key has wrong format" + }, + "500": { + "description": "Internal server error" + } + }, + "requestBody": { + "description": "Public keys", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "publicKeys": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of public keys" + } + }, + "required": [ + "publicKeys" + ] + } + } + }, + "components": { + "schemas": { + "ValidatorPublicKeysDto": { + "type": "object", + "properties": { + "publicKeys": { + "type": "string[]" + } + } + } + } + } + } + } + } + }, + "info": { + "title": "API", + "description": "", + "version": "0.0.1", + "contact": {} + }, + "tags": [], + "servers": [], + "components": { + "schemas": { + "OperatorMetadataDto": { + "type": "object", + "properties": { + "operatorName": { + "type": "string" + }, + "description": { + "type": "string", + "default": "" + }, + "location": { + "type": "string", + "default": "" + }, + "setupProvider": { + "type": "string", + "default": "" + }, + "eth1NodeClient": { + "type": "string", + "default": "" + }, + "eth2NodeClient": { + "type": "string", + "default": "" + }, + "mevRelays": { + "type": "string", + "default": "" + }, + "websiteUrl": { + "type": "string", + "default": "" + }, + "twitterUrl": { + "type": "string", + "default": "" + }, + "linkedinUrl": { + "type": "string", + "default": "" + }, + "dkgAddress": { + "type": "string", + "default": "" + }, + "logo": { + "type": "string", + "description": "Logo as a base64 encoded string" + }, + "signature": { + "type": "string", + "description": "A sign message of the owner of the operator on the operator metadata" + } + }, + "required": [ + "signature" + ] + }, + "DkgHealthCheckDto": { + "type": "object", + "properties": { + "dkgAddress": { + "type": "string" + } + }, + "required": [ + "dkgAddress" + ] + } + } + } + } \ No newline at end of file diff --git a/anchor/http_api/src/schemas/accounts.json b/anchor/http_api/src/schemas/accounts.json new file mode 100644 index 000000000..0f60f61c0 --- /dev/null +++ b/anchor/http_api/src/schemas/accounts.json @@ -0,0 +1,97 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/Accounts", + "definitions": { + "Accounts": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string" + }, + "filter": { + "$ref": "#/definitions/Filter" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/Datum" + } + } + }, + "required": [ + "data", + "filter", + "type" + ], + "title": "Accounts" + }, + "Datum": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer" + }, + "ownerAddress": { + "type": "string" + }, + "recipientAddress": { + "anyOf": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "network": { + "$ref": "#/definitions/Network" + }, + "version": { + "$ref": "#/definitions/Version" + } + }, + "required": [ + "id", + "network", + "ownerAddress", + "recipientAddress", + "version" + ], + "title": "Datum" + }, + "Filter": { + "type": "object", + "additionalProperties": false, + "properties": { + "page": { + "type": "integer" + }, + "perPage": { + "type": "integer" + } + }, + "required": [ + "page", + "perPage" + ], + "title": "Filter" + }, + "Network": { + "type": "string", + "enum": [ + "mainnet" + ], + "title": "Network" + }, + "Version": { + "type": "string", + "enum": [ + "v4" + ], + "title": "Version" + } + } +} diff --git a/anchor/http_api/src/schemas/cluster-count.json b/anchor/http_api/src/schemas/cluster-count.json new file mode 100644 index 000000000..0b4a378cb --- /dev/null +++ b/anchor/http_api/src/schemas/cluster-count.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/ClusterCount", + "definitions": { + "ClusterCount": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string" + }, + "data": { + "type": "integer" + } + }, + "required": [ + "data", + "type" + ], + "title": "ClusterCount" + } + } +} diff --git a/anchor/http_api/src/schemas/cluster-update-error400.json b/anchor/http_api/src/schemas/cluster-update-error400.json new file mode 100644 index 000000000..d3f4a0734 --- /dev/null +++ b/anchor/http_api/src/schemas/cluster-update-error400.json @@ -0,0 +1,60 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/ClusterUpdate400", + "definitions": { + "ClusterUpdate400": { + "type": "object", + "additionalProperties": false, + "properties": { + "error": { + "$ref": "#/definitions/Error" + } + }, + "required": [ + "error" + ], + "title": "ClusterUpdate400" + }, + "Error": { + "type": "object", + "additionalProperties": false, + "properties": { + "code": { + "type": "integer" + }, + "message": { + "$ref": "#/definitions/Message" + } + }, + "required": [ + "code", + "message" + ], + "title": "Error" + }, + "Message": { + "type": "object", + "additionalProperties": false, + "properties": { + "message": { + "type": "array", + "items": { + "type": "string" + } + }, + "error": { + "type": "string" + }, + "statusCode": { + "type": "integer" + } + }, + "required": [ + "error", + "message", + "statusCode" + ], + "title": "Message" + } + } +} diff --git a/anchor/http_api/src/schemas/clusters.json b/anchor/http_api/src/schemas/clusters.json new file mode 100644 index 000000000..8edc31e05 --- /dev/null +++ b/anchor/http_api/src/schemas/clusters.json @@ -0,0 +1,121 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/Clusters", + "definitions": { + "Clusters": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string" + }, + "filter": { + "$ref": "#/definitions/Filter" + }, + "clusters": { + "type": "array", + "items": { + "$ref": "#/definitions/Cluster" + } + } + }, + "required": [ + "clusters", + "filter", + "type" + ], + "title": "Clusters" + }, + "Cluster": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer" + }, + "clusterId": { + "type": "string" + }, + "network": { + "type": "string" + }, + "version": { + "type": "string" + }, + "ownerAddress": { + "type": "string" + }, + "validatorCount": { + "type": "integer" + }, + "networkFeeIndex": { + "type": "string" + }, + "index": { + "type": "string" + }, + "balance": { + "type": "string" + }, + "active": { + "type": "boolean" + }, + "isLiquidated": { + "type": "boolean" + }, + "operators": { + "type": "array", + "items": { + "type": "integer" + } + }, + "blockNumber": { + "type": "integer" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "active", + "balance", + "blockNumber", + "clusterId", + "createdAt", + "id", + "index", + "isLiquidated", + "network", + "networkFeeIndex", + "operators", + "ownerAddress", + "updatedAt", + "validatorCount", + "version" + ], + "title": "Cluster" + }, + "Filter": { + "type": "object", + "additionalProperties": false, + "properties": { + "from": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + }, + "required": [ + "from", + "limit" + ], + "title": "Filter" + } + } +} diff --git a/anchor/http_api/src/schemas/healthcheck.json b/anchor/http_api/src/schemas/healthcheck.json new file mode 100644 index 000000000..4f54cea35 --- /dev/null +++ b/anchor/http_api/src/schemas/healthcheck.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/HealthCheck", + "definitions": { + "HealthCheck": { + "type": "object", + "additionalProperties": false, + "properties": { + "operators": { + "type": "integer" + }, + "validators": { + "type": "integer" + }, + "operators_graph": { + "type": "integer" + }, + "operator": { + "type": "integer" + }, + "validators_in_operator": { + "type": "integer" + } + }, + "required": [ + "operator", + "operators", + "operators_graph", + "validators", + "validators_in_operator" + ], + "title": "HealthCheck" + } + } +} diff --git a/anchor/http_api/src/schemas/merkeltree-notfound.json b/anchor/http_api/src/schemas/merkeltree-notfound.json new file mode 100644 index 000000000..d43f65831 --- /dev/null +++ b/anchor/http_api/src/schemas/merkeltree-notfound.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/MerkeltreeNotFound", + "definitions": { + "MerkeltreeNotFound": { + "type": "object", + "additionalProperties": false, + "properties": { + "error": { + "$ref": "#/definitions/Error" + } + }, + "required": [ + "error" + ], + "title": "MerkeltreeNotFound" + }, + "Error": { + "type": "object", + "additionalProperties": false, + "properties": { + "code": { + "type": "integer" + }, + "message": { + "$ref": "#/definitions/Message" + } + }, + "required": [ + "code", + "message" + ], + "title": "Error" + }, + "Message": { + "type": "object", + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "title": "Message" + } + } +} diff --git a/anchor/http_api/src/schemas/openapi.json b/anchor/http_api/src/schemas/openapi.json new file mode 100644 index 000000000..2e0904890 --- /dev/null +++ b/anchor/http_api/src/schemas/openapi.json @@ -0,0 +1,2364 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "0.1.0", + "title": "ssv api", + "description": "A SSV API that by Sigmaprime - OpenAPI 3.0 specification", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "Swagger API Team" + }, + "license": { + "name": "MIT" + } + }, + "paths": { + "/api/v4/{network}/accounts": { + "get": { + "operationId": "AccountV4Controller_list", + "summary": "List accounts with pagination", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Accounts found and returned in response", + "content": { + "application/json": { + "schema": { + "$ref": "./accounts.json" + } + } + } + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Accounts", + "v4" + ] + } + }, + "/api/v4/{network}/accounts/{ownerAddress}": { + "get": { + "operationId": "AccountV4Controller_byId", + "summary": "Get fee recipient by owner address", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "ownerAddress", + "required": true, + "in": "path", + "description": "Owner address of account", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Account found and returned in response", + "content": { + "application/json": { + "schema": { + "$ref": "./accounts.json" + } + } + } + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Accounts", + "v4" + ] + } + }, + "/api/v4/{network}/accounts/counts/{ownerAddress}": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + }, + { + "name": "ownerAddress", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Owner address" + } + ], + "get": { + "summary": "Get operators and clusters count by owner address", + "tags": [ + "Accounts" + ], + "responses": { + "200": { + "description": "Counts found and returned in response" + }, + "400": { + "description": "Owner address has wrong format" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/v4/{network}/clusters/count": { + "get": { + "operationId": "ClusterV4Controller_count", + "summary": "Count clusters in network", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Clusters counted and returned in response", + "content": { + "application/json": { + "schema": { + "$ref": "./cluster-count.json" + } + } + } + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters": { + "get": { + "operationId": "ClusterV4Controller_list", + "summary": "List clusters with pagination", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "from", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "limit", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "operatorDetails", + "required": false, + "in": "query", + "description": "Response with operators details", + "schema": { + "oneOf": [ + { + "type": "boolean" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Clusters found and returned in response", + "content": { + "application/json": { + "schema": { + "$ref": "./clusters.json" + } + } + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/updates": { + "get": { + "operationId": "ClusterV4Controller_updates", + "summary": "Get clusters updates from specific block number", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "fromBlock", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Cluster updates found and returned in response" + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "./cluster-update-error400.json" + } + } + } + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/{id}": { + "get": { + "operationId": "ClusterV4Controller_byId", + "summary": "Get cluster by its primary ID or keccak256 hash", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "description": "Cluster keccak256 hash ID or primary numeric ID", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "operatorDetails", + "required": false, + "in": "query", + "description": "Response with operator details", + "schema": { + "oneOf": [ + { + "type": "boolean" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Cluster found and returned in response", + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/owner/{owner}/operators/{operators}": { + "get": { + "operationId": "ClusterV4Controller_byOwnerAndOperators", + "summary": "Get cluster by owner address and operators list", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "owner", + "required": true, + "in": "path", + "description": "Owner address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "operators", + "required": true, + "in": "path", + "description": "Comma-separated operator IDs", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "operatorDetails", + "required": false, + "in": "query", + "description": "Response with operators details", + "schema": { + "oneOf": [ + { + "type": "boolean" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Cluster found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/owner/{owner}": { + "get": { + "operationId": "ClusterV4Controller_byOwner", + "summary": "Get clusters by owner address", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Sort by one or few fields.

You can sort only by:   id,  index,  validator_count

Examples:
  1. id:asc,index:desc

  2. validator_count:desc

  3. without specifying sort order: validator_count,id - equals to: validator_count:asc,id:asc

", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "operatorDetails", + "required": false, + "in": "query", + "description": "Response with operators details", + "schema": { + "oneOf": [ + { + "type": "boolean" + } + ] + } + }, + { + "name": "owner", + "required": true, + "in": "path", + "description": "Owner address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Clusters found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/clusters/hash/{clusterHash}": { + "get": { + "operationId": "ClusterV4Controller_validators", + "summary": "Get cluster info (validators and operators) by cluster hash", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "clusterHash", + "required": true, + "in": "path", + "description": "Cluster hash", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Cluster info found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Clusters" + ] + } + }, + "/api/v4/{network}/duties/{validator}": { + "get": { + "operationId": "DutiesV4Controller_duties", + "summary": "List of duties performed by validator", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "validator", + "required": true, + "in": "path", + "description": "Validator address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validator found and duties returned in response" + }, + "400": { + "description": "Validator address has wrong format" + }, + "404": { + "description": "Validator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Duties", + "v4", + "Duties" + ] + } + }, + "/api/v4/{network}/events/{txHash}": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + }, + { + "name": "txHash", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Transaction hash" + } + ], + "get": { + "summary": "Get event by transaction hash", + "tags": [ + "Events" + ], + "responses": { + "200": { + "description": "Event found and returned in response" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/v4/{network}/faucet": { + "get": { + "operationId": "FaucetController_getTransactions", + "summary": "Get transactions by owner address or without", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Faucet" + ] + }, + "post": { + "operationId": "FaucetController_setTransaction", + "summary": "Create transaction by owner address", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ownerAddress", + "network", + "version" + ], + "properties": { + "owner_address": { + "type": "string" + }, + "networkId": { + "type": "number" + }, + "version": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "One or more parameters are invalid" + }, + "406": { + "description": "Reached max transactions per day or faucet depleted" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Faucet" + ] + } + }, + "/api/v4/{network}/faucet/config": { + "get": { + "operationId": "FaucetController_getFaucetConfig", + "summary": "Get transactions config", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Faucet" + ] + } + }, + "/api/finance/currency/convert/{symbol}/{quote}": { + "get": { + "operationId": "FinanceController_currencyConvert", + "summary": "Convert from a currency into a quote currency", + "parameters": [ + { + "name": "symbol", + "required": true, + "in": "path", + "description": "Currency to convert from", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "quote", + "required": true, + "in": "path", + "description": "Currency to convert to", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Both currencies are valid and has been converted", + "content": { + "application/json": { + "schema": { + "properties": { + "symbol": { + "type": "string" + }, + "quote": { + "type": "string" + }, + "price": { + "type": "number" + } + } + } + } + } + }, + "404": { + "description": "Currency can not be found or is not valid", + "content": { + "application/json": { + "schema": { + "properties": { + "symbol": { + "type": "string" + }, + "quote": { + "type": "string" + }, + "error": { + "type": "string" + } + } + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Finance" + ] + } + }, + "/api/v4/{network}/health": { + "get": { + "operationId": "HealthV4Controller_health", + "summary": "Health check", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Health check for all endpoints", + "content": { + "application/json": { + "schema": { + "$ref": "./healthcheck.json" + } + } + } + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Health", + "v4" + ] + } + }, + "/api/v4/{network}/incentivization/merkle-tree": { + "get": { + "operationId": "IncentivizationV4Controller_migrationOperatorsDistribution", + "summary": "Merkle tree for version and network", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Merkle tree found for this version and network" + }, + "404": { + "description": "Merkle tree not found for this version and network", + "content": { + "application/json": { + "schema": { + "$ref": "./merkeltree-notfound.json" + } + } + } + }, + }, + "tags": [ + "Incentivized", + "v4", + "Incentivized" + ] + } + }, + "/api/v4/{network}/operators/graph": { + "get": { + "operationId": "OperatorsV4Controller_graph", + "summary": "List of operators and validators for search widget", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 10000", + "schema": { + "minimum": 1, + "maximum": 10000, + "default": 1000, + "type": "number" + } + }, + { + "name": "randomize", + "required": false, + "in": "query", + "description": "To use this parameter specify \"true\" as string value", + "schema": { + "default": "", + "enum": [ + "true", + "false", + "" + ], + "type": "string" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Operators found and returned in response", + "content": { + "application/json": { + "schema": { + "$ref": "./operators-graph.json" + } + } + } + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators", + "Graph" + ] + } + }, + "/api/v4/{network}/operators/owned_by/{ownerAddress}": { + "get": { + "operationId": "OperatorsV4Controller_ownedBy", + "summary": "List of operators by owner address", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Sort by one or few fields.

You can sort only by:   id,  fee,  public_key,  owner_address,  name,  address,  location,  setup_provider,  eth1_node_client,  eth2_node_client,  description,  website_url,  twitter_url,  linkedin_url,  validators_count,  status,  performance.30d,  performance.24h,  type

Examples:
  1. name:asc,address:desc

  2. validators_count:desc

  3. without specifying sort order: validators_count,name:asc - equals to: validators_count:asc,name:asc

", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "ownerAddress", + "required": true, + "in": "path", + "description": "Owner address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Operators found and returned in response" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/incentivized/{operator}": { + "get": { + "operationId": "OperatorsV4Controller_incentivized", + "summary": "Incentivized stats for operator", + "parameters": [ + { + "name": "epochFrom", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "epochsPerRound", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "rounds", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 5, + "default": 3, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "operator", + "required": true, + "in": "path", + "description": "Operator address or ID from the contract", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Operator found and returned in response" + }, + "400": { + "description": "Operator address has wrong format" + }, + "404": { + "description": "Operator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/{operator}": { + "get": { + "operationId": "OperatorsV4Controller_getOperator", + "summary": "Single operator data", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "operator", + "required": true, + "in": "path", + "description": "Operator address or ID from the contract", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Operator found and returned in response" + }, + "400": { + "description": "Operator id/address has wrong format" + }, + "404": { + "description": "Operator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/dkg_health_check": { + "post": { + "operationId": "OperatorsV4Controller_getDkgHealthCheck", + "summary": "Dkg address health check", + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DkgHealthCheckDto" + } + } + } + }, + "responses": { + "200": { + "description": "true if dkg endpoint is active, false else" + }, + "201": { + "description": "true if dkg endpoint is active, false else" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/public_key/{public_key}": { + "get": { + "operationId": "OperatorsV4Controller_getByPublicKey", + "summary": "Get operator by public key", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "public_key", + "required": true, + "in": "path", + "description": "Operator by public key", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Operator found and returned in response" + }, + "400": { + "description": "Operator public key has wrong format" + }, + "404": { + "description": "Operator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators": { + "get": { + "operationId": "OperatorsV4Controller_operators", + "summary": "List of operators", + "parameters": [ + { + "name": "type", + "required": false, + "in": "query", + "description": "Case-sensitive filter by operator \"type\" in full match manner, comma-separated for multiple matching.

Example:verified_operator, verified_operator,dapp_node, ", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 5000", + "schema": { + "minimum": 1, + "maximum": 5000, + "default": 10, + "type": "number" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Sort by one or few fields.

You can sort only by:   id,  fee,  public_key,  owner_address,  name,  address,  location,  setup_provider,  eth1_node_client,  eth2_node_client,  description,  website_url,  twitter_url,  linkedin_url,  validators_count,  status,  performance.30d,  performance.24h,  type

Examples:
  1. name:asc,address:desc

  2. validators_count:desc

  3. without specifying sort order: validators_count,name:asc - equals to: validators_count:asc,name:asc

", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Full-text search for entries matching all fields in a case-insensitive way", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "has_dkg_address", + "required": false, + "in": "query", + "description": "Filter operators by whether they have a DKG address or not.", + "schema": { + "type": "boolean" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Operators found and returned in response", + "content": { + "application/json": { + "schema": { + "$ref": "./operators.json" + } + } + } + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + }, + "post": { + "operationId": "OperatorsV4Controller_getByIds", + "summary": "List operators by ids", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ids" + ], + "properties": { + "ids": { + "type": "array", + "items": { + "type": "number" + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/{operator}/metadata": { + "put": { + "operationId": "OperatorsV4Controller_updateMetadata", + "summary": "Update operator metadata", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "operator", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperatorMetadataDto" + } + } + } + }, + "responses": { + "200": { + "description": "Operator found and his metadata was updated. Final operator returned in response" + }, + "401": { + "description": "Owner address is not authorized to perform this action" + }, + "404": { + "description": "Operator does not exist" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/nodes/{layer}": { + "get": { + "operationId": "OperatorsV4Controller_nodes", + "summary": "List of available Eth node clients", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "layer", + "required": true, + "in": "path", + "description": "Eth node layer", + "schema": { + "oneOf": [ + { + "type": "string" + } + ], + "enum": [ + "1", + "2" + ] + } + } + ], + "responses": { + "200": { + "description": "List of available Eth node clients" + }, + "400": { + "description": "Layer has wrong format or value" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/operators/locations": { + "get": { + "operationId": "OperatorsV4Controller_locations", + "summary": "List of available locations", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of available locations" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Operators" + ] + } + }, + "/api/v4/{network}/search": { + "get": { + "operationId": "SearchV4Controller_search", + "summary": "Search operators and validators", + "parameters": [ + { + "name": "search", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "searchFor", + "required": false, + "in": "query", + "schema": { + "default": "both", + "enum": [ + "operators", + "validators", + "both" + ], + "type": "string" + } + }, + { + "name": "operatorsLimit", + "required": false, + "in": "query", + "schema": { + "minimum": 0, + "default": 5, + "type": "number" + } + }, + { + "name": "validatorsLimit", + "required": false, + "in": "query", + "schema": { + "minimum": 0, + "default": 5, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Operators or validators found and returned in response" + }, + "400": { + "description": "Search parameters provided with incorrect values" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Search", + "v4" + ] + } + }, + "/api/v4/{network}/validators/countActiveValidators": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + } + ], + "get": { + "summary": "Count active validators in network", + "tags": [ + "Validators" + ], + "responses": { + "200": { + "description": "Validators counted and returned in response" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/v4/{network}/validators/owned_by/{ownerAddress}/cost": { + "get": { + "operationId": "ValidatorsV4Controller_cost", + "summary": "Cost of all validators depending on in which operators they are.", + "parameters": [ + { + "name": "ownerAddress", + "required": true, + "in": "path", + "description": "Owner address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Account address has wrong format" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/in_operator/{operator}": { + "get": { + "operationId": "ValidatorsV4Controller_inOperator", + "summary": "List of validators in operator", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 100", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 10, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "operator", + "required": true, + "in": "path", + "description": "Operator address or ID from the contract", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validators found and returned in response" + }, + "404": { + "description": "No such operator or operator does not have validators" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/incentivized/{validator}": { + "get": { + "operationId": "ValidatorsV4Controller_incentivized", + "summary": "Incentivized stats", + "parameters": [ + { + "name": "epochFrom", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "epochsPerRound", + "required": true, + "in": "query", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "rounds", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 5, + "default": 3, + "type": "number" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "validator", + "required": true, + "in": "path", + "description": "Validator address", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validator found and returned in response" + }, + "400": { + "description": "Validator address has wrong format" + }, + "404": { + "description": "Validator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/{validator}": { + "get": { + "operationId": "ValidatorsV4Controller_validator", + "summary": "Single validator data", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "validator", + "required": true, + "in": "path", + "description": "Validator public_key", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validator found and returned in response" + }, + "400": { + "description": "Validator public_key has wrong format" + }, + "404": { + "description": "Validator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/isRegisteredValidator/{validator}": { + "get": { + "operationId": "ValidatorsV4Controller_validator", + "summary": "If validator is registered - single validator data, 404 otherwise", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "validator", + "required": true, + "in": "path", + "description": "Validator public_key", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Validator found and returned in response" + }, + "400": { + "description": "Validator public_key has wrong format" + }, + "404": { + "description": "Validator not found" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/registeredByPublicKeys": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + } + ], + "post": { + "summary": "Return registered public keys", + "tags": [ + "Validators" + ], + "responses": { + "200": { + "description": "Validators found and returned in response" + }, + "400": { + "description": "Public key has wrong format" + }, + "500": { + "description": "Internal server error" + } + }, + "requestBody": { + "description": "Public keys", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "publicKeys": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of public keys" + } + }, + "required": [ + "publicKeys" + ] + } + } + }, + "components": { + "schemas": { + "RegisteredByPublicKeysDto": { + "type": "object", + "properties": { + "publicKeys": { + "type": "string[]" + } + } + } + } + } + } + } + }, + "/api/v4/{network}/validators": { + "get": { + "operationId": "ValidatorsV4Controller_validators", + "summary": "List of validators", + "parameters": [ + { + "name": "lastId", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "pageDirection", + "required": false, + "in": "query", + "description": "either \"next\" or \"prev\"", + "schema": { + "type": "string" + } + }, + { + "name": "perPage", + "required": false, + "in": "query", + "description": "Maximum allowed value: 1000", + "schema": { + "minimum": 1, + "maximum": 1000, + "default": 10, + "type": "number" + } + }, + { + "name": "ordering", + "required": false, + "in": "query", + "description": "Sort by one or few fields.

You can sort only by:   id,  status,  public_key,  owner_address

Examples:
  1. id:asc,public_key:desc

  2. public_key

  3. without specifying sort order: owner_address,public_key - equals to: owner_address:asc,public_key:asc

", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "ownerAddress", + "required": false, + "in": "query", + "description": "Filter by owner", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Full-text search for entries matching all fields in a case-insensitive way", + "schema": { + "default": "", + "type": "string" + } + }, + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Validators found and returned in response", + "content": { + "application/json": { + "schema": { + "$ref": "./validators.json" + } + } + } + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/duty_counts/{from_epoch}/{to_epoch}": { + "get": { + "operationId": "ValidatorsV4Controller_dutyCounts", + "summary": "Duty counts by validators in an epoch range", + "parameters": [ + { + "name": "network", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "from_epoch", + "required": true, + "in": "path", + "description": "Epoch number", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + }, + { + "name": "to_epoch", + "required": true, + "in": "path", + "description": "Epoch number", + "schema": { + "oneOf": [ + { + "type": "string" + } + ] + } + } + ], + "responses": { + "200": { + "description": "Duty counts found and returned in response" + }, + "404": { + "description": "Requested page number does not exists" + }, + "500": { + "description": "Internal server error" + } + }, + "tags": [ + "Validators" + ] + } + }, + "/api/v4/{network}/validators/validatorsByClusterHash/{clusterHash}": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + }, + { + "name": "clusterHash", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Cluster hash" + } + ], + "get": { + "summary": "Return validator public keys list by cluster hash", + "tags": [ + "Validators" + ], + "responses": { + "200": { + "description": "Validators found and returned in response" + }, + "400": { + "description": "Cluster hash has wrong format" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/v4/{network}/validators/validatorsWithdrawCredentials": { + "parameters": [ + { + "name": "network", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Network name" + } + ], + "post": { + "summary": "Return withdraw credentials", + "tags": [ + "Validators" + ], + "responses": { + "200": { + "description": "Withdraw credentials found and returned in response" + }, + "400": { + "description": "Public key has wrong format" + }, + "500": { + "description": "Internal server error" + } + }, + "requestBody": { + "description": "Public keys", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "publicKeys": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of public keys" + } + }, + "required": [ + "publicKeys" + ] + } + } + }, + "components": { + "schemas": { + "ValidatorPublicKeysDto": { + "type": "object", + "properties": { + "publicKeys": { + "type": "string[]" + } + } + } + } + } + } + } + } + }, + + "tags": [], + "servers": [], + "components": { + "schemas": { + "OperatorMetadataDto": { + "type": "object", + "properties": { + "operatorName": { + "type": "string" + }, + "description": { + "type": "string", + "default": "" + }, + "location": { + "type": "string", + "default": "" + }, + "setupProvider": { + "type": "string", + "default": "" + }, + "eth1NodeClient": { + "type": "string", + "default": "" + }, + "eth2NodeClient": { + "type": "string", + "default": "" + }, + "mevRelays": { + "type": "string", + "default": "" + }, + "websiteUrl": { + "type": "string", + "default": "" + }, + "twitterUrl": { + "type": "string", + "default": "" + }, + "linkedinUrl": { + "type": "string", + "default": "" + }, + "dkgAddress": { + "type": "string", + "default": "" + }, + "logo": { + "type": "string", + "description": "Logo as a base64 encoded string" + }, + "signature": { + "type": "string", + "description": "A sign message of the owner of the operator on the operator metadata" + } + }, + "required": [ + "signature" + ] + }, + "DkgHealthCheckDto": { + "type": "object", + "properties": { + "dkgAddress": { + "type": "string" + } + }, + "required": [ + "dkgAddress" + ] + }, + + } + } +} \ No newline at end of file diff --git a/anchor/http_api/src/schemas/operators-graph.json b/anchor/http_api/src/schemas/operators-graph.json new file mode 100644 index 000000000..95bfeb443 --- /dev/null +++ b/anchor/http_api/src/schemas/operators-graph.json @@ -0,0 +1,277 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/OperatorsGraph", + "definitions": { + "OperatorsGraph": { + "type": "object", + "additionalProperties": false, + "properties": { + "operators": { + "type": "array", + "items": { + "$ref": "#/definitions/Operator" + } + }, + "pagination": { + "$ref": "#/definitions/Pagination" + } + }, + "required": [ + "operators", + "pagination" + ], + "title": "OperatorsGraph" + }, + "Operator": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer" + }, + "id_str": { + "type": "string", + "format": "integer" + }, + "declared_fee": { + "type": "string", + "format": "integer" + }, + "previous_fee": { + "type": "string" + }, + "fee": { + "type": "string", + "format": "integer" + }, + "public_key": { + "type": "string" + }, + "owner_address": { + "type": "string" + }, + "address_whitelist": { + "$ref": "#/definitions/AddressWhitelist" + }, + "is_private": { + "type": "boolean" + }, + "whitelisting_contract": { + "type": "string" + }, + "location": { + "type": "string" + }, + "setup_provider": { + "type": "string" + }, + "eth1_node_client": { + "$ref": "#/definitions/Eth1NodeClient" + }, + "eth2_node_client": { + "$ref": "#/definitions/Eth2NodeClient" + }, + "mev_relays": { + "type": "string" + }, + "description": { + "type": "string" + }, + "website_url": { + "type": "string", + "qt-uri-protocols": [ + "https" + ] + }, + "twitter_url": { + "type": "string", + "qt-uri-protocols": [ + "https" + ] + }, + "linkedin_url": { + "type": "string", + "qt-uri-protocols": [ + "https" + ] + }, + "dkg_address": { + "type": "string", + "qt-uri-protocols": [ + "https" + ] + }, + "logo": { + "type": "string", + "qt-uri-protocols": [ + "https" + ], + "qt-uri-extensions": [ + ".jpeg", + ".png" + ] + }, + "type": { + "$ref": "#/definitions/Type" + }, + "name": { + "type": "string" + }, + "performance": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "is_valid": { + "type": "boolean" + }, + "is_deleted": { + "type": "boolean" + }, + "is_active": { + "type": "integer" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "validators_count": { + "type": "integer" + }, + "version": { + "$ref": "#/definitions/Version" + }, + "network": { + "$ref": "#/definitions/Network" + }, + "whitelist_addresses": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "address_whitelist", + "declared_fee", + "description", + "dkg_address", + "eth1_node_client", + "eth2_node_client", + "fee", + "id", + "id_str", + "is_active", + "is_deleted", + "is_private", + "is_valid", + "linkedin_url", + "location", + "logo", + "mev_relays", + "name", + "network", + "owner_address", + "performance", + "previous_fee", + "public_key", + "setup_provider", + "status", + "twitter_url", + "type", + "validators_count", + "version", + "website_url", + "whitelisting_contract" + ], + "title": "Operator" + }, + "Pagination": { + "type": "object", + "additionalProperties": false, + "properties": { + "total": { + "type": "integer" + }, + "pages": { + "type": "integer" + }, + "per_page": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "current_first": { + "type": "integer" + }, + "current_last": { + "type": "integer" + } + }, + "required": [ + "current_first", + "current_last", + "page", + "pages", + "per_page", + "total" + ], + "title": "Pagination" + }, + "AddressWhitelist": { + "type": "string", + "enum": [ + "", + "0x1DB131C9061e84B74b1abfc2593FDb77F330262E" + ], + "title": "AddressWhitelist" + }, + "Eth1NodeClient": { + "type": "string", + "enum": [ + "", + "Nethermind", + "Besu" + ], + "title": "Eth1NodeClient" + }, + "Eth2NodeClient": { + "type": "string", + "enum": [ + "", + "Lighthouse", + "Nimbus" + ], + "title": "Eth2NodeClient" + }, + "Network": { + "type": "string", + "enum": [ + "mainnet" + ], + "title": "Network" + }, + "Status": { + "type": "string", + "enum": [ + "Active" + ], + "title": "Status" + }, + "Type": { + "type": "string", + "enum": [ + "operator" + ], + "title": "Type" + }, + "Version": { + "type": "string", + "enum": [ + "v4" + ], + "title": "Version" + } + } +} diff --git a/anchor/http_api/src/schemas/operators.json b/anchor/http_api/src/schemas/operators.json new file mode 100644 index 000000000..09be290ea --- /dev/null +++ b/anchor/http_api/src/schemas/operators.json @@ -0,0 +1,262 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/Operators", + "definitions": { + "Operators": { + "type": "object", + "additionalProperties": false, + "properties": { + "operators": { + "type": "array", + "items": { + "$ref": "#/definitions/Operator" + } + }, + "pagination": { + "$ref": "#/definitions/Pagination" + } + }, + "required": [ + "operators", + "pagination" + ], + "title": "Operators" + }, + "Operator": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer" + }, + "id_str": { + "type": "string", + "format": "integer" + }, + "declared_fee": { + "type": "string", + "format": "integer" + }, + "previous_fee": { + "type": "string" + }, + "fee": { + "type": "string", + "format": "integer" + }, + "public_key": { + "type": "string" + }, + "owner_address": { + "type": "string" + }, + "address_whitelist": { + "type": "string" + }, + "whitelist_addresses": { + "type": "array", + "items": { + "type": "string" + } + }, + "is_private": { + "type": "boolean" + }, + "whitelisting_contract": { + "type": "string" + }, + "location": { + "type": "string" + }, + "setup_provider": { + "type": "string" + }, + "eth1_node_client": { + "$ref": "#/definitions/Eth1NodeClient" + }, + "eth2_node_client": { + "type": "string" + }, + "mev_relays": { + "type": "string" + }, + "description": { + "type": "string" + }, + "website_url": { + "type": "string", + "qt-uri-protocols": [ + "https" + ] + }, + "twitter_url": { + "type": "string", + "qt-uri-protocols": [ + "https" + ] + }, + "linkedin_url": { + "type": "string", + "qt-uri-protocols": [ + "https" + ] + }, + "dkg_address": { + "type": "string", + "qt-uri-protocols": [ + "https" + ] + }, + "logo": { + "type": "string", + "format": "uri", + "qt-uri-protocols": [ + "https" + ], + "qt-uri-extensions": [ + ".jpeg", + ".png" + ] + }, + "type": { + "$ref": "#/definitions/Type" + }, + "name": { + "type": "string" + }, + "performance": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "is_valid": { + "type": "boolean" + }, + "is_deleted": { + "type": "boolean" + }, + "is_active": { + "type": "integer" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "validators_count": { + "type": "integer" + }, + "version": { + "$ref": "#/definitions/Version" + }, + "network": { + "$ref": "#/definitions/Network" + } + }, + "required": [ + "address_whitelist", + "declared_fee", + "description", + "dkg_address", + "eth1_node_client", + "eth2_node_client", + "fee", + "id", + "id_str", + "is_active", + "is_deleted", + "is_private", + "is_valid", + "linkedin_url", + "location", + "logo", + "mev_relays", + "name", + "network", + "owner_address", + "performance", + "previous_fee", + "public_key", + "setup_provider", + "status", + "twitter_url", + "type", + "validators_count", + "version", + "website_url", + "whitelist_addresses", + "whitelisting_contract" + ], + "title": "Operator" + }, + "Pagination": { + "type": "object", + "additionalProperties": false, + "properties": { + "total": { + "type": "integer" + }, + "pages": { + "type": "integer" + }, + "per_page": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "current_first": { + "type": "integer" + }, + "current_last": { + "type": "integer" + } + }, + "required": [ + "current_first", + "current_last", + "page", + "pages", + "per_page", + "total" + ], + "title": "Pagination" + }, + "Eth1NodeClient": { + "type": "string", + "enum": [ + "Nethermind", + "Geth", + "Besu" + ], + "title": "Eth1NodeClient" + }, + "Network": { + "type": "string", + "enum": [ + "mainnet" + ], + "title": "Network" + }, + "Status": { + "type": "string", + "enum": [ + "Active" + ], + "title": "Status" + }, + "Type": { + "type": "string", + "enum": [ + "verified_operator" + ], + "title": "Type" + }, + "Version": { + "type": "string", + "enum": [ + "v4" + ], + "title": "Version" + } + } +} diff --git a/anchor/http_api/src/tests.rs b/anchor/http_api/src/tests.rs new file mode 100644 index 000000000..0b9caf53c --- /dev/null +++ b/anchor/http_api/src/tests.rs @@ -0,0 +1,45 @@ +#[cfg(test)] +use super::*; + +// Server starts successfully when enabled with valid config +#[tokio::test] +async fn server_starts_with_valid_config() { + let config = Config { + allow_origin: Some("*".to_string()), + ..Default::default() + }; + + let result = run(config).await; + + assert!(result.is_ok()); +} + +// // Server fails to bind to already in-use port +#[tokio::test] +// #[ignore] +async fn server_fails_on_port_conflict() { + let port = 8080; + let addr = "127.0.0.1".parse().unwrap(); + + // Create a listener to occupy the port + let _existing = TcpListener::bind((addr, port)) + .await + .expect("Failed to bind first listener"); + + let config = Config { + allow_origin: Some("*".to_string()), + enabled: true, + listen_addr: addr, + listen_port: port, + }; + + let result = run(config).await; + + let err_string = result.unwrap_err().to_string(); + + assert!( + err_string.contains("in use") || err_string.contains("EADDRINUSE"), + "Expected error about port conflict, got: {}", + err_string + ); +} diff --git a/anchor/http_api/templates/endpoints.j2 b/anchor/http_api/templates/endpoints.j2 new file mode 100644 index 000000000..d8019347a --- /dev/null +++ b/anchor/http_api/templates/endpoints.j2 @@ -0,0 +1,319 @@ +{# type=tags,filename=api/endpoint.rs,min_version=0.5.0 #} +{%- import "macros.j2" as m -%} +{%- import "extra.j2" as e -%} +{{ m::do_not_modify() }} +use async_trait::async_trait; +use axum::{body::Body, http::{HeaderValue, Response, StatusCode}, response::IntoResponse, Json, http}; +use garde::Validate; +use serde::{ + de::{self, IntoDeserializer}, + Deserialize, +}; +use serde_qs::Error; +use std::fmt; +use axum::extract::FromRequestParts; +use axum::http::request::Parts; + +{% set_global froms = [] %} +{% set_global froms_with_headers = [] %} + + +#[derive(Debug)] +pub struct FailedToDeserializeQuery(Error); + +impl IntoResponse for FailedToDeserializeQuery { + fn into_response(self) -> axum::response::Response { + (http::StatusCode::BAD_REQUEST, self.0.to_string()).into_response() + } +} + +{% for tag in tags -%} +{%- for endpoint in tag.endpoints -%} +{% if endpoint.parameters.path | length > 0 -%} +/// {{ endpoint.method | upper }} {{ endpoint.path }} +/// path parameters +#[derive({% if not options.skipValidate %}Validate, {% endif %}Deserialize)] +pub struct {{ endpoint.operation | pascalcase }}Path{ + {%- for param in endpoint.parameters.path %} + {{- m::model_validation(model = param.model, options = options, regex_path="super::model::") }} + #[serde(rename = "{{ param.name }}"{% if property.required %}, skip_serializing_if = "Option::is_none"{% endif %})] + pub {{ m::property_name(name = param.name) }}: {{ m::type(property = param.model) }}, + {% endfor %} +} +{% endif -%} + +{%- if endpoint.parameters.query | length > 0 %} +{% set object_query_params = endpoint.parameters.query | filter(attribute="model.type", value="object") | length == 0 %} +{% set object_all_optional = endpoint.parameters.query | filter(attribute="required", value=true) | length == 0 %} + +/// {{ endpoint.method | upper }} {{ endpoint.path }} +/// query parameters +#[derive({% if not options.skipValidate %}Validate, {% endif %}Deserialize{% if object_all_optional %},Default{% endif %})] +pub struct {{ endpoint.operation | pascalcase }}Query{ + {%- for param in endpoint.parameters.query %} + {%- if param.style == 'form' and param.explode == false %} + {{ m::model_validation(model = param.model, options = options, is_required=param.required, regex_path="super::model::", style="form") }} + #[serde(rename = "{{ param.name }}", deserialize_with = "deserialized_{% if not param.required %}opt_{% endif %}id_list"{% if property.required %}, skip_serializing_if = "Option::is_none"{% endif %})] + pub {{ m::property_name(name = param.name) }}: {% if not param.required %}Option<{% endif %}Vec<{{ m::type(property = param.model, ns = "super::model") }}{% if not param.required %}>{% endif %}>, + {%- else %} + {{ m::model_validation(model = param.model, options = options, is_required=param.required, regex_path="super::model::") }} + #[serde(rename = "{{ param.name }}"{% if property.required %}, skip_serializing_if = "Option::is_none"{% endif %})] + pub {{ m::property_name(name = param.name) }}: {% if not param.required %}Option<{% endif %}{{ m::type(property = param.model, ns = "super::model") }}{% if not param.required %}>{% endif %}, + {%- endif %} + {% endfor %} +} + +{% endif -%} + +{% set skipped_headers = e::skipped_headers(endpoint=endpoint, options=options) | split(pat=" ") %} +{% set filtered_headers = endpoint.parameters.header | filter_not_inarray(attribute="name", values=skipped_headers) %} +{%- if filtered_headers | length > 0 %} +/// {{ endpoint.method | upper }} {{ endpoint.path }} +/// request headers +#[derive({% if not options.skipValidate %}Validate, {% endif %}Deserialize)] +pub struct {{ endpoint.operation | pascalcase }}RequestHeaders{ + {%- for param in filtered_headers %} + {{- m::model_validation(model = param.model, options = options, is_required=param.required, regex_path="super::model::") }} + #[serde(rename = "{{ param.name }}"{% if property.required %}, skip_serializing_if = "Option::is_none"{% endif %})] + pub {{ m::property_name(name = param.name) }}: {% if not param.required %}Option<{% endif %}{{ m::type(property = param.model, ns = "super::model") }}{% if not param.required %}>{% endif %}, + {% endfor %} +} + +impl std::convert::TryFrom<&axum::http::HeaderMap> for {{ endpoint.operation | pascalcase }}RequestHeaders { + type Error = StatusCode; + + fn try_from(value: &axum::http::HeaderMap) -> Result { + Ok(Self { + {% for param in filtered_headers %} + {{ m::property_name(name = param.name) }}: value.get("{{ param.name }}") + .map(|hv| hv.to_str()) + .map_or(Ok(None), |v| v.map(Some)) + .map_err(|_| StatusCode::BAD_REQUEST)? + .map(|s| s.to_string()) + {% if param.required %}.ok_or(StatusCode::BAD_REQUEST)?{% endif %}, + {% endfor %} + }) + } +} +{% endif -%} + +{% for response in endpoint.responses.all %} +{% set filtered_response_headers = response.headers | default(value=[]) | filter_not_inarray(attribute="name", values=skipped_headers) %} +{% if filtered_response_headers | length > 0 %} +/// {{ endpoint.method | upper }} {{ endpoint.path }} +/// response headers +#[derive(Deserialize)] +pub struct {{ endpoint.operation | pascalcase }}Response{{ response.statusCode }}Headers{ + {% for param in filtered_response_headers %} + #[serde(rename = "{{ param.name }}"{% if property.required %}, skip_serializing_if = "Option::is_none"{% endif %})] + pub {{ m::property_name(name = param.name) }}: {% if not param.required %}Option<{% endif %}{{ m::type(property = param.model, ns = "super::model") }}{% if not param.required %}>{% endif %}, + {% endfor %} +} +{% endif %} +{% endfor %} + +{% for response in endpoint.responses.all %} +{% set filtered_response_headers = response.headers | default(value=[]) | filter_not_inarray(attribute="name", values=skipped_headers) %} +{% if filtered_response_headers | length > 0 %} +{% if not response.models.default.model.model %} +{% elif froms_with_headers is not containing(response.models.default.model.model.name) %} +pub struct {{ m::type(property = response.models.default.model, ns = "") }}WithHeaders { + pub body: {{ m::type(property = response.models.default.model, ns = "super::model") }}, + pub headers: {{ endpoint.operation | pascalcase }}Response{{ response.statusCode }}Headers +} + +{% set_global froms_with_headers = froms_with_headers | concat(with=response.models.default.model.model.name) %} +{% endif %} +{% endif %} +{% endfor %} + +pub enum {{ endpoint.operation | pascalcase }}Response { + {% for response in endpoint.responses.all -%} + {% set filtered_response_headers = response.headers | default(value=[]) | filter_not_inarray(attribute="name", values=skipped_headers) %} + {%- if not response.models -%} + Status{{ response.statusCode }}{% if filtered_response_headers | length > 0 %}({{ endpoint.operation | pascalcase }}Response{{ response.statusCode }}Headers){% endif %}, + {%- else -%} + Status{{ response.statusCode }}({% if filtered_response_headers | length == 0 %}{{ m::type(property = response.models.default.model, ns = "super::model") }}{% else %}{{ m::type(property = response.models.default.model, ns = "") }}WithHeaders{% endif %}), + {%- endif -%} + {% endfor %} +} + +impl IntoResponse for {{ endpoint.operation | pascalcase }}Response { + fn into_response(self) -> axum::response::Response { + self.into() + } +} + +impl From<{{ endpoint.operation | pascalcase }}Response> for Response { + fn from(response: {{ endpoint.operation | pascalcase }}Response) -> Response { + match response { + {% for response in endpoint.responses.all %} + {% set filtered_response_headers = response.headers | default(value=[]) | filter_not_inarray(attribute="name", values=skipped_headers) %} + {{ endpoint.operation | pascalcase }}Response::Status{{ response.statusCode }} + {%- if response.models -%} + (model) => + {% if filtered_response_headers | length > 0 %} + { + let mut response = {{ e::into_response(response = response, name = "model.body") }}; + let headers = response.headers_mut(); + + {% if filtered_response_headers | filter(attribute="required", value=true) | length > 0 %} + {% for param in filtered_response_headers | filter(attribute="required", value=true) %} + headers.insert("{{ param.name | lower }}", HeaderValue::from_str(&model.headers.{{ m::property_name(name = param.name) }}).unwrap()); + {% endfor %}; + {% endif %} + + {% for param in filtered_response_headers | filter(attribute="required", value=false) %} + if let Some(header) = model.headers.{{ m::property_name(name = param.name) }} { + headers.insert("{{ param.name | lower }}", HeaderValue::from_str(&header).unwrap()); + } + {% endfor %} + + response + } + {% else %} + {{ e::into_response(response = response, name = "model") }} + {% endif %} + + {%- elif filtered_response_headers | length > 0 %}(h) => { + let mut response = StatusCode::from_u16({{ response.statusCode }}).unwrap().into_response(); + let headers = response.headers_mut(); + + {% if filtered_response_headers | filter(attribute="required", value=true) | length > 0 %} + {% for param in filtered_response_headers | filter(attribute="required", value=true) %} + headers.insert("{{ param.name | lower }}", HeaderValue::from_str(&h.{{ m::property_name(name = param.name) }}).unwrap()); + {% endfor %}; + {% endif %} + + {% for param in filtered_response_headers | filter(attribute="required", value=false) %} + if let Some(header) = h.{{ m::property_name(name = param.name) }} { + headers.insert("{{ param.name | lower }}", HeaderValue::from_str(&header).unwrap()); + } + {% endfor %} + + response + } + {%- else %} => StatusCode::from_u16({{ response.statusCode }}).unwrap().into_response(){% endif %}, + {% endfor %} + } + } +} + + +{% for response in endpoint.responses.all %} +{% set filtered_response_headers = response.headers | default(value=[]) | filter_not_inarray(attribute="name", values=skipped_headers) %} + + +{% for model in response.models.all | default(value=[]) | filter(attribute="isUnique", value=true) %} +{% if filtered_response_headers | length == 0 %} +impl From<{{ m::type(property = model.model, ns = "super::model") }}> for {{ endpoint.operation | pascalcase }}Response { + fn from(data: {{ m::type(property = model.model, ns = "super::model") }}) -> Self { + Self::Status{{ response.statusCode }}( + data + ) + } + +} +{% endif %} +{% endfor %} + +{% endfor %} +{% endfor %} +{% endfor %} + + + +/// all convertable Result are acceptable +macro_rules! impl_from_result { + ($t:ident) => { + impl From> for $t + where + O: Into<$t>, + E: Into<$t>, + { + fn from(res: Result) -> Self { + match res { + Ok(r) => r.into(), + Err(e) => e.into(), + } + } + } + }; +} + +{% for tag in tags -%} +{% for endpoint in tag.endpoints %} +impl_from_result!({{ endpoint.operation | pascalcase }}Response); +{%- endfor %} +{%- endfor %} + +/// custom deserializer for query parameters /users?id=3,4,5 +/// style = form, explode = false according to https://swagger.io/docs/specification/serialization/ +pub fn deserialized_id_list<'de, D, I>(deserializer: D) -> std::result::Result, D::Error> +where + D: de::Deserializer<'de>, + I: de::DeserializeOwned, +{ + struct StringVecVisitor(std::marker::PhantomData); + + impl<'de, I> de::Visitor<'de> for StringVecVisitor + where I: de::DeserializeOwned { + type Value = Vec; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a string containing a list") + } + + fn visit_str(self, v: &str) -> std::result::Result + where + E: de::Error, + { + let mut ids = Vec::new(); + for id in v.split(',') { + let id = I::deserialize(id.into_deserializer())?; + ids.push(id); + } + Ok(ids) + } + } + + deserializer.deserialize_any(StringVecVisitor(std::marker::PhantomData::)) +} + +pub fn deserialized_opt_id_list<'de, D, I>(deserializer: D) -> std::result::Result>, D::Error> +where + D: de::Deserializer<'de>, + I: de::DeserializeOwned, +{ + struct StringVecVisitor(std::marker::PhantomData); + + impl<'de, I> de::Visitor<'de> for StringVecVisitor + where I: de::DeserializeOwned { + type Value = Option>; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a string containing a list") + } + + fn visit_str(self, v: &str) -> std::result::Result + where + E: de::Error, + { + let mut ids = Vec::new(); + for id in v.split(',') { + let id = I::deserialize(id.into_deserializer())?; + ids.push(id); + } + Ok(Some(ids)) + } + + fn visit_none(self) -> std::result::Result + where + E: de::Error, + { + Ok(None) + } + } + + deserializer.deserialize_any(StringVecVisitor(std::marker::PhantomData::)) +} diff --git a/anchor/http_api/templates/extensions.j2 b/anchor/http_api/templates/extensions.j2 new file mode 100644 index 000000000..d19e60c6b --- /dev/null +++ b/anchor/http_api/templates/extensions.j2 @@ -0,0 +1 @@ +{% macro model_object_impl(model, options) %}{% endmacro model_object_impl %} \ No newline at end of file diff --git a/anchor/http_api/templates/extra.j2 b/anchor/http_api/templates/extra.j2 new file mode 100644 index 000000000..2017cdbbc --- /dev/null +++ b/anchor/http_api/templates/extra.j2 @@ -0,0 +1,91 @@ +{%- import "macros.j2" as m -%} + +{% macro log(type, options) -%}{% filter trim %} +{% if options.log | default(value = "tracing") == "tracing" %} +tracing::{{ type }}! +{% elif options.log == "log" %} +log::{{ type }}! +{% endif %} +{% endfilter %}{%- endmacro log %} + +{% macro skipped_headers(endpoint, options) -%}{% filter trim %} +traceparent tracestate +{% endfilter %}{%- endmacro skipped_headers %} + +{% macro into_response(response, name) -%} +{%- if response.models.default.model.type == "string" %} +model.into_response() +{%- else %} +(StatusCode::from_u16({{ response.statusCode }}).unwrap(), Json({{ name }})).into_response() +{% endif %} +{%- endmacro into_response %} + +{% macro endpoint_parameters(endpoint) -%} +{%- set skipped_headers = self::skipped_headers(endpoint=endpoint, options=options) | split(pat=" ") -%} +{%- set filtered_headers = endpoint.parameters.header | filter_not_inarray(attribute="name", values=skipped_headers) -%} +{%- if endpoint.parameters.path | length > 0 -%} +super::endpoint::{{ endpoint.operation | pascalcase }}Path, +{%- endif -%} +{%- if endpoint.parameters.query | length > 0 -%} +super::endpoint::{{ endpoint.operation | pascalcase }}Query, +{%- endif -%} +{%- if endpoint.requestbody.models.default -%} +super::model::{{ m::model_name(name = endpoint.requestbody.models.default.model.model.name) }}, +{%- endif -%} +{%- if filtered_headers | length > 0 -%} +super::endpoint::{{ endpoint.operation | pascalcase }}RequestHeaders, +{%- endif -%} +{%- endmacro endpoint_parameters %} + +{% macro handler_definition_body(endpoint, options, filtered_headers) -%} +{%- set qs = options.qs | default(value = "serde_urlencoded") -%} +{%- set extract = options.extract | default(value = "axum::extract") -%} +{%- set extra = endpoint.parameters.path | length > 0 or endpoint.parameters.query | length > 0 or endpoint.requestbody.models.default %} + {%- if extra %} + {%- if endpoint.parameters.path | length > 0 %} + let path = match {{ extract }}::Path::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + {%- endif %} + + {%- if endpoint.parameters.query | length > 0 %} + let query = match {% if qs == "serde_qs" %}super::qs::Query{% else %}{{ extract }}::Query{% endif %}::::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + {%- endif %} + {%- endif %} + +{%- endmacro handler_definition_body %} + +{% macro handler_definition_body_fr(endpoint, options, filtered_headers) -%} +{%- set qs = options.qs | default(value = "serde_urlencoded") -%} +{%- set extract = options.extract | default(value = "axum::extract") -%} +{%- set extra = filtered_headers | length > 0 or endpoint.requestbody.models.default %} + {%- if extra %} + let req = Request::from_parts(parts, body); + {%- if filtered_headers | length > 0 %} + let headers = match super::endpoint::{{ endpoint.operation | pascalcase }}RequestHeaders::try_from(req.headers()) { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + {% endif %} + + {%- if endpoint.requestbody.models.default -%} + let body = match {% if extract == 'axum::extract' %}axum::{% else %}{{ extract }}::{% endif %}Json::::from_request(req, state).await { + Ok(value) => value, + Err(err) => return err.into_response(), + }; + {%- endif %} + {%- endif %} + +{%- endmacro handler_definition_body_fr %} + + +{% macro handler_definition_parameters(endpoint, options, filtered_headers) -%} +{%- if endpoint.parameters.path | length > 0 -%}, path.0{%- endif -%} +{%- if endpoint.parameters.query | length > 0 -%}, query.0{%- endif %} +{%- if endpoint.requestbody.models.default -%}, body.0{%- endif -%} +{%- if filtered_headers | length > 0 -%}, headers{%- endif -%} +{%- endmacro handler_definition_parameters %} diff --git a/anchor/http_api/templates/macros.j2 b/anchor/http_api/templates/macros.j2 new file mode 100644 index 000000000..3abedf55e --- /dev/null +++ b/anchor/http_api/templates/macros.j2 @@ -0,0 +1,250 @@ +{% macro property_name(name) %}{% filter nospaces %} + {{ name | replace(from="-", to="") | when_numeric(prefix="n") | snakecase }} + + {% if name | snakecase in [ + "false", "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod", "move", + "mut", "pub", "ref", "return", "self", "static", "struct", "super", "trait", + "true", "type", "unsafe", "use", "where", "while", "async", "await", "dyn", + "abstract", "become", "box", "do", "final", "macro", "override", "priv", "typeof", + "unsized", "virtual", "yield", "try", "result" + ] %}_{% endif %} +{% endfilter %}{% endmacro property_name %} + +{% macro has_format(format, models) -%} +{% for model in models | filter(attribute="object") -%} +{% for property in model.object.properties -%} +{% if property.validation and property.validation.format and property.validation.format == format %}1{% endif %} +{%- endfor %} +{%- endfor %} +{%- endmacro has_format %} + +{% macro model_name(name) %}{% filter nospaces %} + {{ name }} +{% endfilter %}{% endmacro model_name %} + +{% macro is_primitive(type) %}{% filter nospaces %}{% endfilter %}{% endmacro is_primitive %} + +{% macro to_string(q, required, name='') %}{% filter nospaces %} +{% if name != "" %} +{% set real_name = name -%} +{% else %} +{% set real_name = "self." | concat(with=self::property_name(name = q.name)) -%} +{% endif %} +{% if q.type == "enum" %} + {{ real_name }}.to_string() +{% elif q.type == "string" %} + {{ real_name }}.clone() +{% else %} + format!("{}", {{ real_name }}) +{% endif %} +{% endfilter %}{% endmacro to_string %} + +{% macro to_str(q, name='') %}{% filter nospaces %} +{% if name != "" %} +{% set real_name = name -%} +{% else %} +{% set real_name = "self." | concat(with=self::property_name(name = q.name)) -%} +{% endif %} +{% if q.type == "enum" %} + {{ real_name }}.to_string().as_ref() +{% elif q.type == "string" %} + {{ real_name }}.as_ref() +{% else %} + format!("{}", {{ real_name }}).as_ref() +{% endif %} +{% endfilter %}{% endmacro to_str %} + +{% macro enum_variant(name, base) %}{% filter nospaces %} +{{ name | pascalcase | when_numeric(prefix=base) }} +{% endfilter %}{% endmacro enum_variant %} + +{% macro get_validation(validation, regex_path="", form=false) %}{% filter nospaces %} + {% if validation.format and validation.format in ["decimal", "uuid"] %} + {% else %} + {% if validation.minLength %}length(min = {{ validation.minLength }}{% if validation.maxLength %}, max = {{ validation.maxLength }}{% endif %}), {% endif %} + {% if validation.maxLength and not validation.minLength %}length(max = {{ validation.maxLength }}), {% endif %} + {% if validation.minItems %}length(min = {{ validation.minItems }}{% if validation.maxItems %}, max = {{ validation.maxItems }}{% endif %}), {% endif %} + {% if validation.maxItems and not validation.minItems %}length(max = {{ validation.maxItems }}), {% endif %} + {% if form %}inner({% endif %} + {% if validation.pattern %}pattern({{ regex_path }}{{ validation.pattern.name | snakecase | upper }}), {% endif %} + {% if validation.minimum is defined or validation.maximum is defined %} + range( + {% if validation.minimum is defined %}min = {{ validation.minimum }}{% if validation.maximum is defined %}, {% endif %}{% endif %} + {% if validation.maximum is defined %}max = {{ validation.maximum }}{% endif %} + ) + {% endif %} + {% if form %}){% endif %} + {% endif %} +{% endfilter %}{% endmacro get_validation %} + +{% macro model_validation(model, options, is_required=true, regex_path="", style="") %}{% filter nospaces %} + {%- if not options.skipValidate %} + {%- if model.validation and model.type != 'enum' %} + {%- if self::get_validation(validation = model.validation, form = style == "form") | length %} + #[garde( + {% if not is_required -%}inner({%- endif -%} + {{ self::get_validation(validation = model.validation, regex_path = regex_path, form = style == "form") }} + {%- if model.type == "array" and model.model.validation and model.model.type != "enum" %} + {% if not model.required -%}inner({%- endif -%} + {%- if model.nullable -%}inner({%- endif -%} + inner({{ self::get_validation(validation = model.model.validation, regex_path = regex_path) }}) + {%- if model.nullable -%}){%- endif %} + {%- if not model.required -%}){%- endif %} + {% endif %} + {%- if not is_required -%}){%- endif %} + )] + {%- else %} + #[garde(skip)] + {%- endif %} + {%- elif model.type == 'array' and model.model.validation and model.model.type != "enum" %} + {%- if self::get_validation(validation = model.model.validation, form = style == "form") | length %} + #[garde( + {%- if not is_required -%}inner({%- endif -%} + {%- if not model.required -%}inner({%- endif -%} + {%- if model.nullable -%}inner({%- endif -%} + inner({{ self::get_validation(validation = model.model.validation, regex_path = regex_path, form = style == "form") }}) + {%- if model.nullable -%}){%- endif %} + {%- if not model.required -%}){%- endif -%} + {%- if not is_required -%}){%- endif -%} + )] + {%- else %} + #[garde(skip)] + {%- endif %} + {%- elif self::need_nested_validation(property=model) == "1" %} + #[garde(dive)] + {%- else %} + #[garde(skip)] + {%- endif %} + {%- endif %} +{% endfilter %}{% endmacro model_validation %} + +{% macro enum_validation(option, options, regex_path="") %}{% filter nospaces %} + {%- if not options.skipValidate %} + {%- if option.x._discriminator.value.model %} + #[garde(dive)] + {%- else %} + #[garde(skip)] + {%- endif %} + {%- endif %} +{% endfilter %}{% endmacro model_validation %} + +{% macro type(property, ns="") %}{% filter nospaces %} +{% if property.nullable %}Option<{% endif %} + +{# todo: model name cannot be one of json-schema types, infinite loop, check #} + +{% if property.x.type %} + {{ property.x.type }} +{% elif property.validation and property.validation.format and property.validation.format == "decimal" %} + Decimal +{% elif property.type == "string" %} + {% if property.validation and property.validation.format and property.validation.format == "uuid" %} + uuid::Uuid + {% elif property.validation and property.validation.format and property.validation.format == "date-time" %} + DateTime + {% else %} + String + {% endif %} +{% elif property.type == "boolean" %} + bool +{% elif property.type == "integer" and property.validation.minimum | default(value = -1) >= 0 %} + u64 +{% elif property.type == "integer" %} + i64 +{% elif property.type == "number" %} + f64 +{% elif property.type == "any" %} + serde_json::Value +{% elif property.type == "array" and property.model %} + Vec<{{ self::type(property = property.model, ns = ns) }}> +{% elif property.type == "map" and property.model %} + BTreeMap +{% elif property.type == "object" and property.model %} + {% if ns %}{{ ns }}::{% endif %}{{ self::model_name(name = property.model.type) }} +{% elif property.type == "wrapper" and property.model %} + {% if ns %}{{ ns }}::{% endif %}{{ self::model_name(name = property.model.name) }} +{% elif property.type == "enum" and property.model %} + {% if ns %}{{ ns }}::{% endif %}{{ self::model_name(name = property.model.name) }}Variant +{% endif %} + +{% if property.nullable %}>{% endif %} +{% endfilter %}{% endmacro type %} + +{% macro do_not_modify() %} +// +// This file is generated from openapi specification. Please do not modify it. +// It should be .gitignored +// +#![allow(warnings)] +#![allow(clippy::all)] +{% endmacro do_not_modify %} + +{% macro get_auth_header(security) -%} +{% if security.scheme == 'basic' %}Authorization{% else %}{{ security.name }}{% endif %} +{%- endmacro get_auth_header %} + +{% macro endpoint_return(success, endpoint, headers, options) -%}{% filter nospaces %}Result< + {% if success == "no-models" or success.contentType is not starting_with("application/json") %} + {% if success.model and success.model.type == "object" and success.model.model and success.model.model.name %} + {{ self::endpoint_model_response(success = success, headers = headers) }} + {% elif success.model and success.model.type == "wrapper" and success.model.model and success.model.model.type %} + {{ self::endpoint_model_response(success = success, headers = headers) }} + {% else %} + {{ self::endpoint_default_response(endpoint = endpoint, options = options) }} + {% endif %} + {% elif success.model %} + {{ self::endpoint_model_response(success = success, headers = headers) }} + {% else %} + reqwest::Response + {% endif %}, + {{ self::endpoint_error(endpoint = endpoint, options = options) }} +>{% endfilter %}{%- endmacro skipped_headers %} + +{% macro endpoint_model_response(success, headers) -%} + {% if headers | length > 0 %}({% endif %} + {{ self::type(property = success.model, ns = "model") }} + {% if headers | length > 0 %}, reqwest::header::HeaderMap + ){% endif %} +{%- endmacro endpoint_model_response %} +{% macro endpoint_default_response(endpoint, options) -%}endpoint::{{ endpoint.operation | pascalcase }}Response{%- endmacro endpoint_default_response %} + +{% macro endpoint_error(endpoint, options) -%}{% filter nospaces %} +{% if options.errorWrapperType %}{{ options.errorWrapperType }}{% else %}ClientError<{{ self::endpoint_error_body(endpoint = endpoint, options = options) }}>{% endif %} +{% endfilter %}{%- endmacro skipped_headers %} + +{% macro endpoint_error_body(endpoint, options) -%}{% filter nospaces %} +{% if options.globalError %} + {{ options.globalError }} +{% else %} + endpoint::{{ endpoint.operation | pascalcase }}Error +{% endif %} +{% endfilter %}{%- endmacro skipped_headers %} + +{% macro endpoint_map_error(reqwest, endpoint, options) %}{% filter nospaces %} + ClientError::<{{ self::endpoint_error_body(endpoint = endpoint, options = options) }}>::from_reqwest({{ reqwest }}) +{% endfilter %}{% endmacro endpoint_map_error %} + +{% macro endpoint_handle_error(response, endpoint, options) %}{% filter nospaces %} + ClientError::<{{ self::endpoint_error_body(endpoint = endpoint, options = options) }}>::from_response({{ response }}).await +{% endfilter %}{% endmacro endpoint_handle_error %} + +{% macro model_to_string(name, property) %}{% filter nospaces %} +{% if property.type == "enum" %} +{{ name }}.to_string() +{% elif property.type == "string" %} +{{ name }} +{% else %} +/* todo */ +{% endif %} +{% endfilter %}{% endmacro model_to_string %} + +{% macro need_nested_validation(property) %}{% filter nospaces %} + {% if property.model and property.model.type == "array" and property.model.model %} + {{ self::need_nested_validation(property = property.model.model) }} + {% elif property.type == "map" and property.model.type == "any" %} + 0 + {% elif property.type != "enum" and not property.x.type and property.model and property.model.type not in [ + "string", "number", "integer", "boolean", "bool", "null", "enum"] %} + 1 + {% endif %} +{% endfilter %}{% endmacro need_nested_validation %} diff --git a/anchor/http_api/templates/mod.j2 b/anchor/http_api/templates/mod.j2 new file mode 100644 index 000000000..50eeafd79 --- /dev/null +++ b/anchor/http_api/templates/mod.j2 @@ -0,0 +1,11 @@ +{# type=static,filename=api/mod.rs,min_version=0.5.0 #} +{%- import "macros.j2" as m -%} +#![allow(dead_code, unused_imports, unused_variables, clippy::all)] +{{ m::do_not_modify() }} + +pub mod endpoint; +pub mod model; +pub mod service; +{%- if options.qs | default(value = "serde_urlencoded") == "serde_qs" %} +pub mod qs; +{% endif %} \ No newline at end of file diff --git a/anchor/http_api/templates/models-server.j2 b/anchor/http_api/templates/models-server.j2 new file mode 100644 index 000000000..0ca8f9134 --- /dev/null +++ b/anchor/http_api/templates/models-server.j2 @@ -0,0 +1,2 @@ +{# type=models,filename=api/model.rs,min_version=0.2.0 #} +{% extends "models.j2" %} \ No newline at end of file diff --git a/anchor/http_api/templates/models.j2 b/anchor/http_api/templates/models.j2 new file mode 100644 index 000000000..5a6c950c0 --- /dev/null +++ b/anchor/http_api/templates/models.j2 @@ -0,0 +1,176 @@ +{% import "macros.j2" as m -%} +{% import "extensions.j2" as e -%} +{# if wrappers include #} +{{ m::do_not_modify() }} +use serde::{Serialize, Deserialize, Deserializer}; +use std::collections::BTreeMap; +{% if not options.skipValidate %}use garde::Validate; +use regex::Regex; +use once_cell::sync::Lazy;{% endif %} +{% block use %}{% endblock use %} + +{% if formats is containing("decimal") %} +use rust_decimal::Decimal; +{% endif %} +{% if formats is containing("date-time") %} +use chrono::{DateTime, Utc}; +{% endif %} + +{% if not options.skipValidate %} +pub static UUID: Lazy = Lazy::new(|| { Regex::new(r"^\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b$").unwrap() }); +pub static FLOAT: Lazy = Lazy::new(|| { Regex::new(r"^[0-9\.]+$").unwrap() }); +{% for regexp in regexps -%} +pub static {{ regexp.name | snakecase | upper }}: Lazy = Lazy::new(|| { Regex::new(r"{{ regexp.pattern }}").unwrap() }); +{% endfor %} +{% endif %} + +{% for model in models %} +{%- if model.object %} +#[derive(Deserialize, Serialize, Debug,{% if not options.skipValidate %} Validate,{% endif %} Clone{% if model.object.properties | filter(attribute="required", value=true) | length == 0 %}, Default{% endif %})] +pub struct {{ m::model_name(name = model.object.name) }} { + {%- set filtered_properties = model.object.properties | filter_not(attribute="type", value="const") -%} + {% for property in filtered_properties -%} + {{- m::model_validation(model = property, options = options) }} + #[serde(rename = "{{ property.name }}"{% if not property.required and property.nullable %}, default, deserialize_with = "optional_nullable"{% elif not property.required %}, skip_serializing_if = "Option::is_none"{% endif %})] + pub {{ m::property_name(name = property.name) }}: {% if not property.required %}Option<{% endif %}{{ m::type(property = property) }}{% if not property.required %}>{% endif %}, + {%- endfor %} +} + +impl {{ m::model_name(name = model.object.name) }} { {# if sort required first #} + pub fn new({%- for property in filtered_properties -%}{{ m::property_name(name = property.name) }}: {% if not property.required %}Option<{% endif %}{{ m::type(property = property) }}{% if not property.required %}>{% endif %}, {% endfor %}) -> Self { + Self { + {% for property in filtered_properties %}{{ m::property_name(name = property.name) }}, + {% endfor %} + } + } + + {% for property in model.object.properties | filter(attribute="type", value="const") -%} + // todo: add to serialization as static + pub fn get_{{ m::property_name(name = property.name) }}(&self) -> {{ m::type(property = property.model) }} { + {% if property.model.type == "string" %} + "{{ property.model.name }}".to_string() + {% endif %} + } + {% endfor %} +} + +{{ e::model_object_impl(model = model, options = options) }} + +{%- elif model.enum %} +#[derive({%- if model.enum.type == "number" %}serde_repr::Serialize_repr, serde_repr::Deserialize_repr{% else %}Deserialize, Serialize{% endif %}, Debug, Clone{% if not options.skipValidate %}, Validate{% endif %})] +{%- if model.enum.type == "number" %} +#[repr(u32)] +{%- endif %} +pub enum {{ m::model_name(name = model.enum.name) }}Variant { + {% for option in model.enum.options -%} + {% if option == option | when_numeric(prefix="n") | pascalcase -%} + {{ option }}, + {%- elif model.enum.type == "number" %} + {{ m::enum_variant(name = option, base = m::model_name(name = model.enum.name) ) }} = {{ option }}, + {%- elif option is matching("^[\d]+") %} + #[serde(rename = "{{ option }}")] + {%set a = 'Code' ~ option %} + {{ m::enum_variant(name = a, base = m::model_name(name = a)) }}, + {%- else %} + #[serde(rename = "{{ option }}")] + {{ m::enum_variant(name = option, base = m::model_name(name = model.enum.name)) }}, + {% endif %} + {%- endfor %} +} + +impl std::string::ToString for {{ m::model_name(name = model.enum.name) }}Variant { + fn to_string(&self) -> String { + match self { + {%- for option in model.enum.options %} + Self::{%- if option == option | when_numeric(prefix="n") | pascalcase -%} + {{ option }} + {%- elif model.enum.type == "number" -%} + {{ m::enum_variant(name = option, base = m::model_name(name = model.enum.name) ) }} + {%- elif option is matching("^[\d]+") -%} + {% set a = 'Code' ~ option %} + {{ m::enum_variant(name = a, base = m::model_name(name = a)) }} + {%- else -%} + {{ m::enum_variant(name = option, base = m::model_name(name = model.enum.name)) }} + {%- endif %} => "{{ option }}", + {%- endfor %} + }.to_string() + } +} + +impl std::str::FromStr for {{ m::model_name(name = model.enum.name) }}Variant { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + {%- for option in model.enum.options %} + "{{ option }}" => Ok(Self::{%- if option == option | when_numeric(prefix="n") | pascalcase -%} + {{ option }} + {%- elif model.enum.type == "number" -%} + {{ m::enum_variant(name = option, base = m::model_name(name = model.enum.name) ) }} + {%- elif option is matching("^[\d]+") -%} + {% set a = 'Code' ~ option %} + {{ m::enum_variant(name = a, base = m::model_name(name = a)) }} + {%- else -%} + {{ m::enum_variant(name = option, base = m::model_name(name = model.enum.name)) }} + {%- endif %}), + {%- endfor %} + _ => Err(()) + } + } +} + +{%- elif model.wrapper %} +{% if model.wrapper.strategy and model.wrapper.strategy == "externally" %} +#[derive(Debug, Clone, {% if not options.skipValidate %}Validate, {% endif %}Deserialize, Serialize)] +pub enum {{ m::model_name(name = model.wrapper.name) }} { + {% for option in model.wrapper.models -%} + #[serde(rename = "{{ option.x._discriminator.property }}")] + {{ option.x._discriminator.property | pascalcase }}( + {%- if option.x._discriminator.value.model -%} + {{- m::enum_validation(option = option, options = options) }} + {{ option.x._discriminator.value.model.name }}{% if option.x._discriminator.value.model.kind == 'string' %}Variant{% endif %} + {%- elif option.x._discriminator.value.simple -%} + {{- m::enum_validation(option = option, options = options) }} + {{ m::type(property = option.x._discriminator.value.simple) }} + {%- endif -%} + ), + {% endfor %} +} + +{% elif model.wrapper.strategy.internally %} +#[derive(Debug, Clone, {% if not options.skipValidate %}Validate, {% endif %}Deserialize, Serialize)] +#[serde(tag = "{{ model.wrapper.strategy.internally }}")] +pub enum {{ m::model_name(name = model.wrapper.name) }} { + {% for option in model.wrapper.models -%} + #[serde(rename = "{{ option.x._discriminator.value.model.name }}")] + {{ option.x._discriminator.value.model.name | pascalcase }}{% if option.x._discriminator.properties | default(value = 0) > 0 %}({{- m::enum_validation(option = option, options = options) }}{{ m::type(property = option) }}){% endif %}, + {% endfor %} +} + +{% else -%} +#[derive(Debug, Clone, {% if not options.skipValidate %}Validate, {% endif %}Serialize, Deserialize)] +#[serde(untagged)] +pub enum {{ m::model_name(name = model.wrapper.name) }} { + {% for option in model.wrapper.models -%} + {{ m::type(property = option) | pascalcase }}( + {{- m::enum_validation(option = option, options = options) }} + {{ m::type(property = option) }} + ), + {% endfor %} +} + +{% endif -%} + +{%- elif model.primitive %} +pub type {{ m::model_name(name = model.primitive.name) }} = {{ m::type(property = model.primitive) }}; +{% endif %} +{% endfor %} + +pub fn optional_nullable<'de, T, D>(deserializer: D) -> Result, D::Error> + where T: Deserialize<'de>, + D: Deserializer<'de> +{ + Deserialize::deserialize(deserializer).map(Some) +} + +{% block end %}{% endblock end %} diff --git a/anchor/http_api/templates/qs.j2 b/anchor/http_api/templates/qs.j2 new file mode 100644 index 000000000..5de46bf39 --- /dev/null +++ b/anchor/http_api/templates/qs.j2 @@ -0,0 +1,56 @@ +{# type=static,filename=api/qs.rs,min_version=0.5.0,if=%options.qs%:serde_qs #} +{%- import "extra.j2" as e -%} +{%- import "macros.j2" as m -%} +{{ m::do_not_modify() }} +use std::{pin::Pin, sync::Arc}; + +use async_trait::async_trait; +use axum::{ + extract::{rejection::QueryRejection, FromRequest, Request}, + http, + response::{IntoResponse, Response}, + BoxError, +}; +use serde::de::{self, DeserializeOwned}; +use serde_qs::Error; +use std::ops::Deref; +use axum::extract::FromRequestParts; +use axum::http::request::Parts; + +#[derive(Debug, Clone, Copy, Default)] +pub struct Query(pub T); + +#[async_trait] +impl FromRequestParts for Query + where + T: DeserializeOwned, + S: Send + Sync, +{ + type Rejection = FailedToDeserializeQueryStringRejection; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let query = parts.uri.query().unwrap_or_default(); + + let value = + serde_qs::from_str::(query).map_err(FailedToDeserializeQueryStringRejection)?; + + Ok(Query(value)) + } +} + +impl Deref for Query { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug)] +pub struct FailedToDeserializeQueryStringRejection(Error); + +impl IntoResponse for FailedToDeserializeQueryStringRejection { + fn into_response(self) -> Response { + (http::StatusCode::BAD_REQUEST, self.0.to_string()).into_response() + } +} \ No newline at end of file diff --git a/anchor/http_api/templates/service.j2 b/anchor/http_api/templates/service.j2 new file mode 100644 index 000000000..d1e527083 --- /dev/null +++ b/anchor/http_api/templates/service.j2 @@ -0,0 +1,265 @@ +{# type=tags,filename=api/service.rs,min_version=0.5.0 #} +{%- import "macros.j2" as m -%} +{%- import "extra.j2" as e -%} +{%- set strict_router = options.relaxedRouter is not defined -%} +{{ m::do_not_modify() }} +{%- if strict_router %} +use axum::{ + body::{Body, HttpBody}, + extract::{FromRequest, FromRequestParts, Request as ERequest}, + handler::{future::IntoServiceFuture, Handler}, + http::Request, + response::{IntoResponse, Response}, + routing::{self, on_service, MethodFilter}, + Router, BoxError, +}; +use futures::{future::LocalBoxFuture, Future}; +use std::{ + convert::{Infallible, TryFrom}, + marker::PhantomData, + pin::Pin, + task::{Context, Poll}, +}; +use tower_service::Service; +{%- else %} +use axum::{ + routing::{get, post, delete, patch, put, options, MethodRouter}, + handler::Handler, + Router, +}; +{%- endif %} + +{%- if strict_router %} +macro_rules! all_the_tuples { + ($name:ident) => { + $name!(T1); + $name!(T1, T2); + $name!(T1, T2, T3); + $name!(T1, T2, T3, T4); + $name!(T1, T2, T3, T4, T5); + } +} +{%- endif %} + +{%- for tag in tags %} + +/// {{ tag.tag }} router +pub struct {{ tag.tag | pascalcase }}Router { + pub(crate) router: Router, +} + +impl {{ tag.tag | pascalcase }}Router where S: Clone + Send + Sync + 'static { + pub fn new() -> Self { + Self { + router: Router::new() + } + } + + {%- for endpoint in tag.endpoints %} + + /// {{ endpoint.method | upper }} {{ endpoint.path }} + /// + /// # Examples + /// + /// ``` + /// async fn handler({{ e::endpoint_parameters(endpoint = endpoint) | trim_end_matches(pat=",") }}) -> {{ endpoint.operation | pascalcase }}Response { + /// todo!(); + /// } + /// let router = {{ tag.tag | pascalcase }}Router::default().{{ endpoint.operation | snakecase }}(handler); + /// ``` + /// + /// ``` + /// async fn handler({{ e::endpoint_parameters(endpoint = endpoint) | trim_end_matches(pat=",") }}, ...extractors) -> {{ endpoint.operation | pascalcase }}Response { + /// todo!(); + /// } + /// let router = {{ tag.tag | pascalcase }}Router::default().{{ endpoint.operation | snakecase }}(handler); + /// ``` + pub fn {{ endpoint.operation | snakecase }}(mut self, handler: H) -> Self + where + H: {% if strict_router %}{{ endpoint.operation | pascalcase }}Handler{% else %}Handler + Clone + Send + Sync + 'static{% endif %}, + T: 'static + { + self.router = self.router.route("{{ endpoint.path | replace(from="{", to=":") | replace(from="}", to="") }}", {% if strict_router -%}on_service(MethodFilter::{{ endpoint.method | upper }}, {{ endpoint.operation | pascalcase }}Service::new{%- else -%}{{ endpoint.method | lower }}{%- endif -%}(handler){% if strict_router %}){% endif %}); + self + } + {%- endfor %} +} + +impl Default for {{ tag.tag | pascalcase }}Router where S: Clone + Send + Sync + 'static { + fn default() -> Self { + Self::new() + } +} + +impl From<{{ tag.tag | pascalcase }}Router> for Router { + fn from(r: {{ tag.tag | pascalcase }}Router) -> Self { + r.router + } +} + +{%- if strict_router %} +{% for endpoint in tag.endpoints %} +{%- set skipped_headers = e::skipped_headers(endpoint=endpoint, options=options) | split(pat=" ") %} +{%- set filtered_headers = endpoint.parameters.header | filter_not_inarray(attribute="name", values=skipped_headers) %} +/// {{ endpoint.method | upper }} {{ endpoint.path }} handler +pub trait {{ endpoint.operation | pascalcase }}Handler: Clone + Send + Sized + 'static { + fn call( + self, + req: ERequest, + state: S + ) -> Pin + Send + 'static>>; +} + +impl {{ endpoint.operation | pascalcase }}Handler<(), S, B> for F +where + F: FnOnce({{ e::endpoint_parameters(endpoint = endpoint) }}) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + {% if endpoint.requestbody.models.default -%} + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + {% else %} + B: Send + 'static, + {% endif %} + S: Send + Sync + 'static, +{ + {%- set body = e::handler_definition_body(endpoint = endpoint, options = options, filtered_headers = filtered_headers) -%} + {%- set body_fr = e::handler_definition_body_fr(endpoint = endpoint, options = options, filtered_headers = filtered_headers) -%} + fn call( + self, + {% if not body and not body_fr %}_{% endif %}req: ERequest, + state: S + ) -> Pin + Send + 'static>> { + Box::pin(async move { + {% if body or body_fr -%} + let (mut parts, body) = req.into_parts(); + let state = &state; + +{{ body }} +{{ body_fr }} +{%- endif %} + + let res = self( + {%- filter trim_start_matches(pat=", ") -%} + {{ e::handler_definition_parameters(endpoint = endpoint, options = options, filtered_headers = filtered_headers)}}, {% endfilter -%} + ).await; + + let response: super::endpoint::{{ endpoint.operation | pascalcase }}Response = res.into(); + + response.into() + }) + } +} + +macro_rules! {{ endpoint.operation | snakecase }}_handler { + ( $($ty:ident),* $(,)? ) => { + #[allow(non_snake_case)] + impl {{ endpoint.operation | pascalcase }}Handler<($($ty,)*), S, B> for F + where + F: FnOnce({{ e::endpoint_parameters(endpoint = endpoint) }}$($ty,)*) -> Fut + Clone + Send + 'static, + Fut: Future + Send, + Fut::Output: Into, + {%- if endpoint.requestbody.models.default -%} + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into, + {%- else %} + B: Send + 'static, + {%- endif %} + S: Send + Sync + 'static, + $( $ty: FromRequestParts + Send,)* + { + fn call(self, req: ERequest, state: S) -> Pin + Send + 'static>> { + Box::pin(async move { + let (mut parts, body) = req.into_parts(); + let state = &state; + + {{ e::handler_definition_body(endpoint = endpoint, options = options, filtered_headers = filtered_headers) }} + + $( + let $ty = match $ty::from_request_parts(&mut parts, state).await { + Ok(value) => value, + Err(rejection) => return rejection.into_response(), + }; + )* + + + {{ e::handler_definition_body_fr(endpoint = endpoint, options = options, filtered_headers = filtered_headers) }} + + let res = self({%- filter trim_start_matches(pat=", ") -%} + {{ e::handler_definition_parameters(endpoint = endpoint, options = options, filtered_headers = filtered_headers)}}, {% endfilter -%} + $($ty,)*).await; + + let response: super::endpoint::{{ endpoint.operation | pascalcase }}Response = res.into(); + + response.into() + }) + } + } + }; +} + +all_the_tuples!({{ endpoint.operation | snakecase }}_handler); + +/// {{ endpoint.method | upper }} {{ endpoint.path }} service +struct {{ endpoint.operation | pascalcase }}Service +where + H: {{ endpoint.operation | pascalcase }}Handler { + handler: H, + _marker: PhantomData (T, S)>, +} + +impl Clone for {{ endpoint.operation | pascalcase }}Service +where + H: {{ endpoint.operation | pascalcase }}Handler +{ + fn clone(&self) -> Self { + Self { + handler: self.handler.clone(), + _marker: PhantomData, + } + } +} + +impl {{ endpoint.operation | pascalcase }}Service +where + H: {{ endpoint.operation | pascalcase }}Handler { + pub fn new(handler: H) -> Self { + Self { + handler, + _marker: PhantomData, + } + } +} + +impl Service for {{ endpoint.operation | pascalcase }}Service +where + H: {{ endpoint.operation | pascalcase }}Handler, + S: Send + Sync + 'static { + type Response = Response; + type Error = Infallible; + type Future = Pin> + Send + 'static>>; + + #[inline] + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, mut req: ERequest) -> Self::Future { + let handler = self.handler.clone(); + + Box::pin(async move { + let state = req + .extensions_mut() + .remove::() + .expect("state extension missing. This is a bug in code schema-tools, please file an issue"); + + Ok( {{ endpoint.operation | pascalcase }}Handler::call(handler, req, state).await) + }) + } +} + +{% endfor %} +{%- endif %} +{%- endfor %}