Files
khadhroony-solana-project/crates/ksp-config-lib/src/offchain_transport.rs
2026-08-26 12:06:51 +02:00

521 lines
22 KiB
Rust

// file: crates/ksp-config-lib/src/offchain_transport.rs
// version: 2
//! Adapter from Config-owned Off-chain Transport documents to the provider-agnostic market-price runtime service.
/// Effective standard Off-chain Transport configuration resolved from Config.
pub struct ResolvedOffchainTransportConfig {
effective: crate::ResolvedConfigJson,
file_id: crate::ConfigFileId,
profile_id: String,
selection_source: crate::ConfigProfileSelectionSource,
service: ksp_offchain_transport_lib::MarketPriceService,
source_path: std::path::PathBuf,
}
impl crate::ResolvedOffchainTransportConfig {
/// Returns the detailed environment-resolved effective Config view with secret-safe diagnostics.
#[must_use]
pub const fn effective(&self) -> &crate::ResolvedConfigJson {
return &self.effective;
}
/// Returns the logical Config document identifier used by this runtime configuration.
#[must_use]
pub const fn file_id(&self) -> &crate::ConfigFileId {
return &self.file_id;
}
/// Returns the selected standard Off-chain Transport profile identifier.
#[must_use]
pub fn profile_id(&self) -> &str {
return self.profile_id.as_str();
}
/// Returns the source that selected the standard Off-chain Transport profile.
#[must_use]
pub const fn selection_source(&self) -> crate::ConfigProfileSelectionSource {
return self.selection_source;
}
/// Returns the provider-agnostic market-price runtime service.
#[must_use]
pub const fn service(&self) -> &ksp_offchain_transport_lib::MarketPriceService {
return &self.service;
}
/// Returns the physical source Config document path.
#[must_use]
pub fn source_path(&self) -> &std::path::Path {
return self.source_path.as_path();
}
}
impl std::fmt::Debug for crate::ResolvedOffchainTransportConfig {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let registry = self.service.registry();
return formatter
.debug_struct("ResolvedOffchainTransportConfig")
.field("effective", &self.effective)
.field("file_id", &self.file_id)
.field("profile_id", &self.profile_id)
.field("provider_registry", &registry)
.field("selection_source", &self.selection_source)
.field("source_path", &self.source_path)
.finish();
}
}
impl crate::ConfigDocumentEngine {
/// Loads the standard Off-chain Transport document and maps one profile to the generic market-price runtime service.
pub fn load_resolved_offchain_transport_config(
&self,
requested_profile: std::option::Option<&str>,
environment: &crate::ConfigEnvironment,
) -> ksp_core_lib::Result<crate::ResolvedOffchainTransportConfig> {
let file_id = crate::ConfigFileId::new(crate::FILE_ID_STD_OFFCHAIN_TRANSPORT);
let file_id = match file_id {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let profile = self.load_resolved_profile(&file_id, requested_profile);
let profile = match profile {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
return resolve_offchain_transport_profile(&profile, environment);
}
/// Maps an already resolved standard Off-chain Transport profile to the runtime service while preserving composite selection provenance.
pub fn resolve_offchain_transport_config_profile(
&self,
profile: &crate::ResolvedConfigProfile,
environment: &crate::ConfigEnvironment,
) -> ksp_core_lib::Result<crate::ResolvedOffchainTransportConfig> {
if profile.file_id().as_str() != crate::FILE_ID_STD_OFFCHAIN_TRANSPORT {
return std::result::Result::Err(effective_error(profile, "resolved Config profile does not reference the standard Off-chain Transport document"));
}
let descriptor = self.registry().descriptor(profile.file_id());
if let std::result::Result::Err(error) = descriptor {
return std::result::Result::Err(error);
}
return resolve_offchain_transport_profile(profile, environment);
}
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct EffectiveOffchainTransportSource {
format_version: u32,
market_price: EffectiveMarketPriceSource,
profile_id: String,
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct EffectiveMarketPriceSource {
birdeye: EffectiveBirdeyeSource,
coinbase_exchange: EffectiveEnabledSource,
coingecko: EffectiveCoinGeckoSource,
coinmarketcap: EffectiveCoinMarketCapSource,
coinpaprika: EffectiveEnabledSource,
dexscreener: EffectiveDexScreenerSource,
jupiter: EffectiveJupiterSource,
kraken: EffectiveEnabledSource,
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct EffectiveEnabledSource {
enabled: bool,
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct EffectiveBirdeyeSource {
api_key: std::option::Option<String>,
enabled: bool,
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct EffectiveCoinGeckoSource {
access_mode: ksp_offchain_transport_lib::MarketPriceCoinGeckoAccessMode,
api_key: std::option::Option<String>,
enabled: bool,
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct EffectiveCoinMarketCapSource {
access_mode: ksp_offchain_transport_lib::MarketPriceCoinMarketCapAccessMode,
api_key: std::option::Option<String>,
enabled: bool,
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct EffectiveDexScreenerSource {
enabled: bool,
sol_usd_pair_address: std::option::Option<String>,
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct EffectiveJupiterSource {
access_mode: ksp_offchain_transport_lib::MarketPriceJupiterAccessMode,
api_key: std::option::Option<String>,
enabled: bool,
}
fn resolve_offchain_transport_profile(
profile: &crate::ResolvedConfigProfile,
environment: &crate::ConfigEnvironment,
) -> ksp_core_lib::Result<crate::ResolvedOffchainTransportConfig> {
ksp_logging_lib::trace!(
target: crate::TRACING_TARGET,
profile_id = profile.profile_id(),
"mapping standard Off-chain Transport Config profile"
);
let effective = profile.resolve_effective_environment_detailed(environment);
let effective = match effective {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let source = serde_json::from_value::<EffectiveOffchainTransportSource>(effective.value().clone());
let source = match source {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(
effective_error(profile, "effective Off-chain Transport Config cannot be decoded into the runtime adapter contract").with_source(error),
);
},
};
if source.format_version != 1 {
return std::result::Result::Err(effective_error(profile, "effective Off-chain Transport format_version is unsupported"));
}
if source.profile_id != profile.profile_id() {
return std::result::Result::Err(effective_error(profile, "effective Off-chain Transport profile_id does not match the selected profile"));
}
let setups = map_market_price_setups(source.market_price, &effective, profile);
let setups = match setups {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let service = ksp_offchain_transport_lib::MarketPriceService::new(setups);
let service = match service {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(offchain_contract_error(
profile,
"effective market-price providers fail the Off-chain Transport runtime contract",
&error,
));
},
};
let provider_count = service.registry().entries().len();
ksp_logging_lib::debug!(
target: crate::TRACING_TARGET,
profile_id = profile.profile_id(),
format_version = source.format_version,
provider_count,
"mapped standard Off-chain Transport Config to market-price service"
);
return std::result::Result::Ok(crate::ResolvedOffchainTransportConfig {
effective,
file_id: profile.file_id().clone(),
profile_id: profile.profile_id().to_owned(),
selection_source: profile.selection_source(),
service,
source_path: profile.path().to_path_buf(),
});
}
fn map_market_price_setups(
source: EffectiveMarketPriceSource,
effective: &crate::ResolvedConfigJson,
profile: &crate::ResolvedConfigProfile,
) -> ksp_core_lib::Result<std::vec::Vec<ksp_offchain_transport_lib::MarketPriceProviderSetup>> {
let birdeye = map_birdeye(source.birdeye, effective, profile);
let birdeye = match birdeye {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let coinbase_exchange = ksp_offchain_transport_lib::MarketPriceCoinbaseExchangeSettings::new(source.coinbase_exchange.enabled);
let coinbase_exchange = match coinbase_exchange {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(provider_contract_error(profile, "coinbase_exchange", &error)),
};
let coingecko = map_coingecko(source.coingecko, effective, profile);
let coingecko = match coingecko {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let coinmarketcap = map_coinmarketcap(source.coinmarketcap, effective, profile);
let coinmarketcap = match coinmarketcap {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let coinpaprika = ksp_offchain_transport_lib::MarketPriceCoinPaprikaSettings::new(source.coinpaprika.enabled);
let coinpaprika = match coinpaprika {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(provider_contract_error(profile, "coinpaprika", &error)),
};
let dexscreener = map_dexscreener(source.dexscreener, effective, profile);
let dexscreener = match dexscreener {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let jupiter = map_jupiter(source.jupiter, effective, profile);
let jupiter = match jupiter {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let kraken = ksp_offchain_transport_lib::MarketPriceKrakenSettings::new(source.kraken.enabled);
let kraken = match kraken {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(provider_contract_error(profile, "kraken", &error)),
};
return std::result::Result::Ok(std::vec![
ksp_offchain_transport_lib::MarketPriceProviderSetup::Birdeye(birdeye),
ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinbaseExchange(coinbase_exchange),
ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinGecko(coingecko),
ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinMarketCap(coinmarketcap),
ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinPaprika(coinpaprika),
ksp_offchain_transport_lib::MarketPriceProviderSetup::DexScreener(dexscreener),
ksp_offchain_transport_lib::MarketPriceProviderSetup::Jupiter(jupiter),
ksp_offchain_transport_lib::MarketPriceProviderSetup::Kraken(kraken),
]);
}
fn map_birdeye(
source: EffectiveBirdeyeSource,
effective: &crate::ResolvedConfigJson,
profile: &crate::ResolvedConfigProfile,
) -> ksp_core_lib::Result<ksp_offchain_transport_lib::MarketPriceBirdeyeSettings> {
if source.api_key.is_some()
&& let std::result::Result::Err(error) = validate_secret_field_provenance(effective, "/market_price/birdeye/api_key", profile, "birdeye")
{
return std::result::Result::Err(error);
}
let settings = ksp_offchain_transport_lib::MarketPriceBirdeyeSettings::new(source.enabled, source.api_key);
return match settings {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
std::result::Result::Err(error) => std::result::Result::Err(provider_contract_error(profile, "birdeye", &error)),
};
}
fn map_coingecko(
source: EffectiveCoinGeckoSource,
effective: &crate::ResolvedConfigJson,
profile: &crate::ResolvedConfigProfile,
) -> ksp_core_lib::Result<ksp_offchain_transport_lib::MarketPriceCoinGeckoSettings> {
if source.api_key.is_some()
&& let std::result::Result::Err(error) = validate_secret_field_provenance(effective, "/market_price/coingecko/api_key", profile, "coingecko")
{
return std::result::Result::Err(error);
}
let settings = match source.access_mode {
ksp_offchain_transport_lib::MarketPriceCoinGeckoAccessMode::Demo => {
ksp_offchain_transport_lib::MarketPriceCoinGeckoSettings::demo(source.enabled, source.api_key)
},
ksp_offchain_transport_lib::MarketPriceCoinGeckoAccessMode::Keyless => {
ksp_offchain_transport_lib::MarketPriceCoinGeckoSettings::keyless(source.enabled)
},
_ => {
return std::result::Result::Err(
effective_error(profile, "Off-chain Transport CoinGecko access mode is not supported by this Config adapter")
.with_context("provider", "coingecko")
.with_context("field", "access_mode"),
);
},
};
return match settings {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
std::result::Result::Err(error) => std::result::Result::Err(provider_contract_error(profile, "coingecko", &error)),
};
}
fn map_coinmarketcap(
source: EffectiveCoinMarketCapSource,
effective: &crate::ResolvedConfigJson,
profile: &crate::ResolvedConfigProfile,
) -> ksp_core_lib::Result<ksp_offchain_transport_lib::MarketPriceCoinMarketCapSettings> {
if source.api_key.is_some()
&& let std::result::Result::Err(error) = validate_secret_field_provenance(effective, "/market_price/coinmarketcap/api_key", profile, "coinmarketcap")
{
return std::result::Result::Err(error);
}
let settings = match source.access_mode {
ksp_offchain_transport_lib::MarketPriceCoinMarketCapAccessMode::Basic => {
ksp_offchain_transport_lib::MarketPriceCoinMarketCapSettings::basic(source.enabled, source.api_key)
},
ksp_offchain_transport_lib::MarketPriceCoinMarketCapAccessMode::Keyless => {
ksp_offchain_transport_lib::MarketPriceCoinMarketCapSettings::keyless(source.enabled)
},
_ => {
return std::result::Result::Err(
effective_error(profile, "Off-chain Transport CoinMarketCap access mode is not supported by this Config adapter")
.with_context("provider", "coinmarketcap")
.with_context("field", "access_mode"),
);
},
};
return match settings {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
std::result::Result::Err(error) => std::result::Result::Err(provider_contract_error(profile, "coinmarketcap", &error)),
};
}
fn map_dexscreener(
source: EffectiveDexScreenerSource,
effective: &crate::ResolvedConfigJson,
profile: &crate::ResolvedConfigProfile,
) -> ksp_core_lib::Result<ksp_offchain_transport_lib::MarketPriceDexScreenerSettings> {
if source.sol_usd_pair_address.is_some()
&& let std::result::Result::Err(error) =
validate_public_field_provenance(effective, "/market_price/dexscreener/sol_usd_pair_address", profile, "dexscreener")
{
return std::result::Result::Err(error);
}
let settings = ksp_offchain_transport_lib::MarketPriceDexScreenerSettings::new(source.enabled, source.sol_usd_pair_address);
return match settings {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
std::result::Result::Err(error) => std::result::Result::Err(provider_contract_error(profile, "dexscreener", &error)),
};
}
fn map_jupiter(
source: EffectiveJupiterSource,
effective: &crate::ResolvedConfigJson,
profile: &crate::ResolvedConfigProfile,
) -> ksp_core_lib::Result<ksp_offchain_transport_lib::MarketPriceJupiterSettings> {
if source.api_key.is_some()
&& let std::result::Result::Err(error) = validate_secret_field_provenance(effective, "/market_price/jupiter/api_key", profile, "jupiter")
{
return std::result::Result::Err(error);
}
let settings = match source.access_mode {
ksp_offchain_transport_lib::MarketPriceJupiterAccessMode::Free => {
ksp_offchain_transport_lib::MarketPriceJupiterSettings::free(source.enabled, source.api_key)
},
ksp_offchain_transport_lib::MarketPriceJupiterAccessMode::Keyless => ksp_offchain_transport_lib::MarketPriceJupiterSettings::keyless(source.enabled),
_ => {
return std::result::Result::Err(
effective_error(profile, "Off-chain Transport Jupiter access mode is not supported by this Config adapter")
.with_context("provider", "jupiter")
.with_context("field", "access_mode"),
);
},
};
return match settings {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
std::result::Result::Err(error) => std::result::Result::Err(provider_contract_error(profile, "jupiter", &error)),
};
}
fn validate_secret_field_provenance(
effective: &crate::ResolvedConfigJson,
pointer: &str,
profile: &crate::ResolvedConfigProfile,
provider: &'static str,
) -> ksp_core_lib::Result<()> {
let provenance = match effective.provenance_at(pointer) {
std::option::Option::Some(value) => value,
std::option::Option::None => {
return std::result::Result::Err(
effective_error(profile, "Off-chain Transport secret provenance is unavailable")
.with_context("provider", provider)
.with_context("field", pointer),
);
},
};
let mut has_secret_environment = false;
for item in provenance {
let variable_name = match item.variable_name() {
std::option::Option::Some(value) => value,
std::option::Option::None => continue,
};
let sensitivity = crate::ConfigSensitivity::from_variable_name(variable_name);
let sensitivity = match sensitivity {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
if !sensitivity.is_secret() {
return std::result::Result::Err(
effective_error(profile, "Off-chain Transport credentials may reference only secret environment variables")
.with_context("provider", provider)
.with_context("field", pointer),
);
}
has_secret_environment = true;
}
if !has_secret_environment {
return std::result::Result::Err(
effective_error(profile, "Off-chain Transport credentials require secret environment provenance")
.with_context("provider", provider)
.with_context("field", pointer),
);
}
return std::result::Result::Ok(());
}
fn validate_public_field_provenance(
effective: &crate::ResolvedConfigJson,
pointer: &str,
profile: &crate::ResolvedConfigProfile,
provider: &'static str,
) -> ksp_core_lib::Result<()> {
let provenance = match effective.provenance_at(pointer) {
std::option::Option::Some(value) => value,
std::option::Option::None => {
return std::result::Result::Err(
effective_error(profile, "Off-chain Transport public provenance is unavailable")
.with_context("provider", provider)
.with_context("field", pointer),
);
},
};
for item in provenance {
let variable_name = match item.variable_name() {
std::option::Option::Some(value) => value,
std::option::Option::None => continue,
};
let sensitivity = crate::ConfigSensitivity::from_variable_name(variable_name);
let sensitivity = match sensitivity {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
if sensitivity != crate::ConfigSensitivity::Public {
return std::result::Result::Err(
effective_error(profile, "public Off-chain Transport fields may reference only public environment variables")
.with_context("provider", provider)
.with_context("field", pointer),
);
}
}
return std::result::Result::Ok(());
}
fn provider_contract_error(profile: &crate::ResolvedConfigProfile, provider: &'static str, error: &ksp_core_lib::Error) -> ksp_core_lib::Error {
return offchain_contract_error(profile, "effective market-price provider settings fail the Off-chain Transport runtime contract", error)
.with_context("provider", provider);
}
fn offchain_contract_error(profile: &crate::ResolvedConfigProfile, reason: &'static str, error: &ksp_core_lib::Error) -> ksp_core_lib::Error {
return effective_error(profile, reason)
.with_context("offchain_transport_error_domain", error.code().domain())
.with_context("offchain_transport_error_code", error.code().code());
}
fn effective_error(profile: &crate::ResolvedConfigProfile, reason: &'static str) -> ksp_core_lib::Error {
return ksp_core_lib::Error::new(crate::ERROR_CODE_EFFECTIVE_CONFIG_INVALID, "effective Config cannot be mapped to the requested runtime contract")
.with_context("file_id", profile.file_id().as_str())
.with_context("profile_id", profile.profile_id())
.with_context("reason", reason);
}
#[cfg(test)]
#[path = "../unit_tests/offchain_transport.rs"]
mod tests;