Files
khadhroony-solana-project/crates/ksp-offchain-transport-lib/tests/public_api.rs
2026-08-26 10:23:42 +02:00

240 lines
13 KiB
Rust

// file: crates/ksp-offchain-transport-lib/tests/public_api.rs
// version: 9
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
//! Public API canaries for the market-price foundation and stable Off-chain Transport error-code surface.
#[test]
fn public_pre_002_market_price_foundation_is_available_from_crate_root() -> ksp_core_lib::Result<()> {
assert_eq!(ksp_offchain_transport_lib::MarketPricePair::SolUsd.code(), "SOL/USD");
assert_eq!(ksp_offchain_transport_lib::MARKET_PRICE_DECIMAL_MAX_SCALE, 18);
let price = match ksp_offchain_transport_lib::MarketPriceDecimal::parse("201.2500") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(price.to_canonical_string(), "201.25");
let id = match ksp_offchain_transport_lib::MarketPriceProviderId::new("provider-canary") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let common = ksp_offchain_transport_lib::MarketPriceProviderCommonSettings::new(id.clone(), true);
assert_eq!(common.provider_id(), &id);
let rate_limit = match ksp_offchain_transport_lib::MarketPriceProviderRateLimit::fixed(
1,
1,
std::option::Option::None,
ksp_offchain_transport_lib::MarketPriceProviderRateLimitScope::Ip,
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let descriptor = match ksp_offchain_transport_lib::MarketPriceProviderDescriptor::new(
id.clone(),
"Provider Canary",
ksp_offchain_transport_lib::MarketPriceSemantics::AggregatedMarket,
ksp_offchain_transport_lib::MarketPriceProviderAuthMode::None,
rate_limit,
std::option::Option::None,
true,
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert!(descriptor.supports_sol_usd());
let provenance = match ksp_offchain_transport_lib::MarketPriceProvenance::new("canary") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let timestamp = ksp_offchain_transport_lib::MarketPriceTimestamp::from_unix_millis(1);
let observation = match ksp_offchain_transport_lib::MarketPriceObservation::new(
id,
price,
ksp_offchain_transport_lib::MarketPriceSemantics::AggregatedMarket,
timestamp,
timestamp,
std::option::Option::None,
provenance,
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(observation.price(), price);
return std::result::Result::Ok(());
}
#[test]
fn public_pre_004_aggregator_settings_and_adapters_are_available_from_crate_root() -> ksp_core_lib::Result<()> {
let coingecko = match ksp_offchain_transport_lib::MarketPriceCoinGeckoSettings::keyless(false) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let coingecko_provider = match ksp_offchain_transport_lib::MarketPriceCoinGeckoProvider::new(coingecko) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(coingecko_provider.descriptor().id().as_str(), "coingecko");
let coinmarketcap = match ksp_offchain_transport_lib::MarketPriceCoinMarketCapSettings::keyless(false) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let coinmarketcap_provider = match ksp_offchain_transport_lib::MarketPriceCoinMarketCapProvider::new(coinmarketcap) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(coinmarketcap_provider.descriptor().id().as_str(), "coinmarketcap");
let coinpaprika = match ksp_offchain_transport_lib::MarketPriceCoinPaprikaSettings::new(false) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let coinpaprika_provider = match ksp_offchain_transport_lib::MarketPriceCoinPaprikaProvider::new(coinpaprika) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(coinpaprika_provider.descriptor().id().as_str(), "coinpaprika");
return std::result::Result::Ok(());
}
#[test]
fn public_pre_005_exchange_settings_and_adapters_are_available_from_crate_root() -> ksp_core_lib::Result<()> {
let kraken = match ksp_offchain_transport_lib::MarketPriceKrakenSettings::new(false) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let kraken_provider = match ksp_offchain_transport_lib::MarketPriceKrakenProvider::new(kraken) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(kraken_provider.descriptor().id().as_str(), "kraken");
assert_eq!(kraken_provider.descriptor().semantics(), ksp_offchain_transport_lib::MarketPriceSemantics::ExchangeLastTrade);
let coinbase = match ksp_offchain_transport_lib::MarketPriceCoinbaseExchangeSettings::new(false) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let coinbase_provider = match ksp_offchain_transport_lib::MarketPriceCoinbaseExchangeProvider::new(coinbase) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(coinbase_provider.descriptor().id().as_str(), "coinbase_exchange");
assert_eq!(coinbase_provider.descriptor().semantics(), ksp_offchain_transport_lib::MarketPriceSemantics::ExchangeLastTrade);
return std::result::Result::Ok(());
}
#[test]
fn public_pre_006_jupiter_and_dexscreener_settings_and_adapters_are_available_from_crate_root() -> ksp_core_lib::Result<()> {
let jupiter = match ksp_offchain_transport_lib::MarketPriceJupiterSettings::keyless(false) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let jupiter_provider = match ksp_offchain_transport_lib::MarketPriceJupiterProvider::new(jupiter) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(jupiter_provider.descriptor().id().as_str(), "jupiter");
assert_eq!(jupiter_provider.descriptor().semantics(), ksp_offchain_transport_lib::MarketPriceSemantics::SolanaHeuristic);
let dexscreener = match ksp_offchain_transport_lib::MarketPriceDexScreenerSettings::new(false, "Czfq3xZZDmsdGdUyrNLtRhGc47cXcZtLG4crryfu44zE") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let dexscreener_provider = match ksp_offchain_transport_lib::MarketPriceDexScreenerProvider::new(dexscreener) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(dexscreener_provider.descriptor().id().as_str(), "dexscreener");
assert_eq!(dexscreener_provider.descriptor().semantics(), ksp_offchain_transport_lib::MarketPriceSemantics::DexPairUsd);
return std::result::Result::Ok(());
}
#[test]
fn public_pre_007_birdeye_and_provider_registry_are_available_from_crate_root() -> ksp_core_lib::Result<()> {
let settings = match ksp_offchain_transport_lib::MarketPriceBirdeyeSettings::new(false, std::option::Option::None) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let provider = match ksp_offchain_transport_lib::MarketPriceBirdeyeProvider::new(settings) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(provider.descriptor().id().as_str(), "birdeye");
assert_eq!(provider.descriptor().semantics(), ksp_offchain_transport_lib::MarketPriceSemantics::SolanaSpot);
let request_cost = match provider.descriptor().sol_usd_request_cost() {
std::option::Option::Some(value) => value,
std::option::Option::None => {
return std::result::Result::Err(ksp_core_lib::Error::new(
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_PROVIDER_DESCRIPTOR_INVALID,
"Birdeye descriptor is missing request-cost metadata",
));
},
};
assert_eq!(request_cost.amount(), 3);
assert_eq!(request_cost.unit(), ksp_offchain_transport_lib::MarketPriceProviderQuotaUnit::ComputeUnits);
let ready = ksp_offchain_transport_lib::MarketPriceProviderAvailability::Ready;
assert!(ready.is_refresh_eligible());
assert_eq!(ready.retry_at(), std::option::Option::None);
let entry = ksp_offchain_transport_lib::MarketPriceProviderRegistryEntry::new(provider.descriptor().clone(), ready);
let registry = match ksp_offchain_transport_lib::MarketPriceProviderRegistry::new(std::vec![entry]) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(registry.len(), 1);
assert_eq!(registry.entries()[0].descriptor().id().as_str(), "birdeye");
return std::result::Result::Ok(());
}
#[tokio::test]
async fn public_pre_008_generic_refresh_service_is_available_without_provider_branching_at_callsite() -> ksp_core_lib::Result<()> {
let settings = match ksp_offchain_transport_lib::MarketPriceCoinPaprikaSettings::new(false) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let service =
match ksp_offchain_transport_lib::MarketPriceService::new(std::vec![ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinPaprika(settings),]) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let registry = service.registry();
let provider_id = registry.entries()[0].descriptor().id().clone();
let outcome = match service.refresh(&provider_id).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(outcome.provider_id(), &provider_id);
assert!(!outcome.refreshed());
assert_eq!(outcome.state().availability(), ksp_offchain_transport_lib::MarketPriceProviderAvailability::Disabled);
return std::result::Result::Ok(());
}
#[test]
fn offchain_error_codes_use_owned_domain() {
let codes = [
ksp_offchain_transport_lib::ERROR_CODE_HTTP_ACCESS_DENIED,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_ADMISSION_DEFERRED,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_CLIENT_BUILD_FAILED,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_CONNECTION_FAILED,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_INVALID_JSON,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_RATE_LIMIT_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_RATE_LIMITED,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_REQUEST_FAILED,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_REQUEST_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_RESPONSE_TOO_LARGE,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_SETTINGS_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_TEMPORARY_FAILURE,
ksp_offchain_transport_lib::ERROR_CODE_HTTP_TIMEOUT,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_DECIMAL_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_PROVIDER_DESCRIPTOR_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_PROVIDER_DISABLED,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_PROVIDER_ID_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_PROVIDER_NOT_FOUND,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_PROVIDER_RESPONSE_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_OBSERVATION_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_PROVIDER_SETTINGS_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_REFRESH_INVALID,
ksp_offchain_transport_lib::ERROR_CODE_MARKET_PRICE_REGISTRY_INVALID,
];
for code in codes {
assert_eq!(code.domain(), "offchain_transport");
}
}