Files
khadhroony-solana-project/crates/ksp-offchain-transport-lib/USAGE.md
2026-08-26 12:06:51 +02:00

6.1 KiB

Usage de ksp-offchain-transport-lib

Cette page montre la surface technique disponible à 0.2.11-pre.010. Les credentials et documents runtime doivent normalement être résolus par ksp-config-lib; les constructions directes ci-dessous servent surtout aux tests, outils bas niveau et compositions programmatiques maîtrisées.

1. Construire un service programmatique

Un service reçoit une liste de MarketPriceProviderSetup. Le setup est provider-specific uniquement au moment de la composition :

let coingecko = ksp_offchain_transport_lib::MarketPriceCoinGeckoSettings::keyless(true)?;
let kraken = ksp_offchain_transport_lib::MarketPriceKrakenSettings::new(true)?;
let service = ksp_offchain_transport_lib::MarketPriceService::new(std::vec![
    ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinGecko(coingecko),
    ksp_offchain_transport_lib::MarketPriceProviderSetup::Kraken(kraken),
])?;

Une application normale n'a pas à reproduire le mapping des huit providers. ksp-config-lib::ResolvedOffchainTransportConfig construit cette composition depuis cfg.std.offchain_transport.

2. Découvrir le registry générique

Après construction, le consumer travaille sur le registry sans matcher les variants provider :

for entry in service.registry().entries() {
    let descriptor = entry.descriptor();
    let state = entry.state();
    println!(
        "{} {:?} {:?}",
        descriptor.display_name(),
        descriptor.semantics(),
        state.availability(),
    );
}

Le provider_id est opaque. Il sert d'identité stable pour rappeler le service, pas de signal autorisant le consumer à reconstruire un endpoint ou une règle provider.

3. Rafraîchir un provider

let provider_id = ksp_offchain_transport_lib::MarketPriceProviderId::new("coingecko")?;
let outcome = service.refresh(&provider_id).await?;

L'outcome expose génériquement l'observation éventuelle et l'état provider. Une erreur provider normalisée n'oblige pas le consumer à parser CoinGecko, Kraken ou Jupiter.

Avant un refresh, l'état peut être consulté via le registry. MarketPriceProviderAvailability::retry_at() expose le prochain instant connu lorsqu'il existe réellement.

4. Rafraîchir plusieurs providers

let ids = service
    .registry()
    .entries()
    .iter()
    .map(|entry| return entry.descriptor().id().clone())
    .collect::<std::vec::Vec<_>>();
let outcomes = service.refresh_many(ids.as_slice()).await?;

La V1 exécute ce batch séquentiellement, dans l'ordre demandé. Elle valide les IDs avant le premier dispatch, rejette les doublons, ne dort pas pour un cooldown et produit un outcome générique par provider lorsque l'opération est valide.

refresh_all() applique le même contrat dans l'ordre stable du registry :

let outcomes = service.refresh_all().await?;

Il n'existe pas de fallback, consensus ou moyenne implicite. Une application voulant comparer les observations doit conserver leurs sémantiques et provenances ; elle ne doit pas présenter leurs différences comme une erreur de KSP.

5. Construire depuis Config

La voie runtime normale est :

let resolved = engine.load_resolved_offchain_transport_config(
    std::option::Option::None,
    &environment,
)?;
let service = resolved.service();
let registry = service.registry();

Le profil public_keyless du document standard peut être résolu sans credentials. Le profil all_free attend les secrets/public fields inventoriés dans .env.example et validés par ksp-config-lib.

Off-chain Transport ne lit pas l'environnement lui-même. Ne passez pas un credential via une URL, une query arbitraire ou une surface UI libre pour contourner Config.

6. DexScreener

DexScreener doit recevoir la paire SOL/USD Solana explicitement approuvée par la composition lorsqu'il est activé :

let pair = ksp_core_lib::Pubkey::parse("<PAIR_ADDRESS_APPROUVEE>")?;
let settings = ksp_offchain_transport_lib::MarketPriceDexScreenerSettings::new(
    true,
    std::option::Option::Some(pair),
)?;

La paire n'est pas un secret. Aucun helper V1 ne découvre automatiquement une autre pool, ne trie par liquidité ou ne remplace la paire configurée.

7. Exactitude numérique

Ne convertissez pas l'observation canonique en f64 pour la stocker ou la comparer comme vérité KSP. MarketPriceDecimal conserve une forme décimale exacte et sérialise une représentation canonique.

Pour l'affichage, un consumer peut utiliser sa représentation textuelle publique. Toute conversion approximative éventuelle appartient à une couche de présentation qui accepte explicitement cette perte ; elle ne doit pas remplacer le type canonique dans le transport.

8. Forward compatibility

Les enums publiques susceptibles d'évoluer sont #[non_exhaustive]. Hors de la crate, les matches doivent donc prévoir un fallback :

match entry.state().availability() {
    ksp_offchain_transport_lib::MarketPriceProviderAvailability::Ready => {},
    ksp_offchain_transport_lib::MarketPriceProviderAvailability::Disabled => {},
    _ => {},
}

La branche _ est intentionnelle : de nouveaux providers, états, sémantiques ou paires pourront être ajoutés sans imposer une rupture source aux consumers bien écrits.

9. Diagnostics sûrs

Les diagnostics applicatifs peuvent journaliser :

provider_id validé
code d'erreur KSP
classe d'availability
retry_at borné lorsqu'il existe
durée/opération générique

Ils ne doivent pas journaliser :

API key
URL complète sensible
header provider secret
body distant brut
payload de Config secret

ksp-offchain-transport-lib utilise ksp-logging-lib et son TRACING_TARGET propriétaire ; une application ne doit pas ajouter un bypass direct tracing pour obtenir les payloads rejetés.

10. Statut documentaire

Ce document est un brouillon technique de pre.010. Il ne vaut ni smoke live, ni garantie commerciale sur les plans gratuits des providers. pre.011 porte les contrôles techniques/live finaux ; pre.012 porte la réconciliation documentaire finale.