281 lines
8.0 KiB
Markdown
281 lines
8.0 KiB
Markdown
<!-- file: deltas/0.2.11/pre.007.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.2.11-pre.007` — Birdeye + registry + availability
|
|
|
|
## 1. Base requise
|
|
|
|
Cette tranche s'applique exclusivement après `0.2.11-pre.006` accepté par l'opérateur.
|
|
|
|
Version Cargo attendue à l'entrée :
|
|
|
|
```text
|
|
0.2.11-pre.6
|
|
```
|
|
|
|
Version Cargo de sortie :
|
|
|
|
```text
|
|
0.2.11-pre.7
|
|
```
|
|
|
|
Le gate d'entrée ciblé du `2026-08-25` est PASS : `cargo fmt --all`, audit Rust clean avec 0 candidate export, audit Markdown clean à 120 tables / 111 fichiers, `cargo check --workspace`, `cargo clippy --workspace --all-targets` et `cargo test -p ksp-offchain-transport-lib` avec 43 unitaires + 4 boundary + 5 public API. `cargo test --workspace` n'a pas été rejoué sur l'état exact `pre.006` avant le passage explicite à cette tranche.
|
|
|
|
## 2. Objet strict de la tranche
|
|
|
|
`pre.007` ferme l'inventaire V1 des huit providers et matérialise le registry provider-neutral :
|
|
|
|
```text
|
|
Birdeye Standard
|
|
MarketPriceProviderRegistry
|
|
MarketPriceProviderRegistryEntry
|
|
availability générique consultable
|
|
metadata de coût provider informatif
|
|
```
|
|
|
|
La tranche n'ajoute pas encore :
|
|
|
|
```text
|
|
refresh(provider_id)
|
|
refresh multiple/all
|
|
service de dispatch provider
|
|
Config Off-chain Transport
|
|
smoke live
|
|
fallback/consensus
|
|
```
|
|
|
|
## 3. Birdeye Standard
|
|
|
|
Ajout de :
|
|
|
|
```text
|
|
market_price_birdeye.rs
|
|
unit_tests/market_price_birdeye.rs
|
|
MarketPriceBirdeyeSettings
|
|
MarketPriceBirdeyeProvider
|
|
```
|
|
|
|
Le réaudit officiel courant confirme :
|
|
|
|
```text
|
|
base URL https://public-api.birdeye.so
|
|
endpoint GET /defi/price
|
|
mint SOL So11111111111111111111111111111111111111112
|
|
chain header x-chain: solana
|
|
auth header X-API-KEY
|
|
Standard 0 USD, 30 000 compute units inclus
|
|
limite compte 1 RPS
|
|
Price Single 3 compute units par appel
|
|
```
|
|
|
|
Une clé Birdeye est obligatoire lorsque le provider est activé. Un provider désactivé peut être construit sans secret afin que Config et le futur service puissent représenter un état non actif sans inventer de credential.
|
|
|
|
La clé reste dans `MarketPriceApiKey`, n'est jamais lue directement depuis l'environnement par Off-chain Transport et n'apparaît ni dans `Debug`, ni dans les logs, ni dans les erreurs.
|
|
|
|
Le request builder utilise uniquement l'origine officielle fixe, le mint WSOL fixe et `x-chain = solana`.
|
|
|
|
La réponse Price Single est normalisée depuis :
|
|
|
|
```text
|
|
data.value
|
|
data.updateUnixTime
|
|
success
|
|
```
|
|
|
|
`data.value` passe par `serde_json::RawValue` puis `MarketPriceDecimal` sans round-trip `f64`. `updateUnixTime` devient un vrai `provider_timestamp` en secondes Unix converties en millisecondes.
|
|
|
|
La sémantique retenue est :
|
|
|
|
```text
|
|
MarketPriceSemantics::SolanaSpot
|
|
```
|
|
|
|
La provenance sûre est :
|
|
|
|
```text
|
|
birdeye:solana:wsol:value
|
|
```
|
|
|
|
Une réponse `success = false`, un prix absent/null, un timestamp absent/pathologique ou un JSON incompatible sont rejetés sans copier le body distant dans les diagnostics.
|
|
|
|
## 4. Quota et coût provider informatifs
|
|
|
|
Birdeye utilise des compute units. Pour ne pas les confondre avec des crédits abstraits ou des requêtes HTTP, `MarketPriceProviderQuotaUnit` gagne :
|
|
|
|
```text
|
|
ComputeUnits
|
|
```
|
|
|
|
`MarketPriceProviderRequestCost` représente un coût unitaire documenté pour l'opération SOL/USD courante.
|
|
|
|
Le descriptor Birdeye expose :
|
|
|
|
```text
|
|
long_term_quota = 30 000 ComputeUnits / Month
|
|
sol_usd_request_cost = 3 ComputeUnits
|
|
```
|
|
|
|
Ces valeurs sont informatives. KSP ne décrémente pas localement le quota et ne prétend pas connaître un solde authoritative : un autre processus ou une autre API du même compte peut consommer les mêmes compute units.
|
|
|
|
`MarketPriceProviderDescriptor::with_sol_usd_request_cost` vérifie que le coût et le quota utilisent la même unité lorsqu'un quota est présent.
|
|
|
|
## 5. Registry provider-neutral
|
|
|
|
Ajout de :
|
|
|
|
```text
|
|
market_price_registry.rs
|
|
unit_tests/market_price_registry.rs
|
|
MarketPriceProviderRegistry
|
|
MarketPriceProviderRegistryEntry
|
|
ERROR_CODE_MARKET_PRICE_REGISTRY_INVALID
|
|
```
|
|
|
|
Une entrée contient seulement :
|
|
|
|
```text
|
|
MarketPriceProviderDescriptor
|
|
MarketPriceProviderState
|
|
```
|
|
|
|
Le registry :
|
|
|
|
```text
|
|
est borné à 64 entrées
|
|
trie les entrées par provider_id
|
|
rejette les provider_id dupliqués
|
|
permet lookup descriptor/state/entry par identifiant opaque
|
|
expose une slice déterministe d'entrées
|
|
ne contient aucun nom ou dispatch provider spécifique
|
|
```
|
|
|
|
Le constructeur reste public et provider-neutral, comme `MarketPriceProviderDescriptor::new` déjà existant. Cela ne donne aucun accès à un endpoint ou à un client HTTP. Le futur service `pre.008` possédera les transitions runtime et le dispatch des adapters ; la HID ne devra pas construire ou matcher des providers spécifiques.
|
|
|
|
Un canari de complétude construit les huit adapters V1 en mode désactivé et vérifie l'inventaire ordonné :
|
|
|
|
```text
|
|
birdeye
|
|
coinbase_exchange
|
|
coingecko
|
|
coinmarketcap
|
|
coinpaprika
|
|
dexscreener
|
|
jupiter
|
|
kraken
|
|
```
|
|
|
|
## 6. Availability générique
|
|
|
|
`MarketPriceProviderAvailability` gagne deux helpers publics provider-neutral :
|
|
|
|
```text
|
|
is_refresh_eligible()
|
|
retry_at()
|
|
```
|
|
|
|
Ils permettent à un consumer d'interpréter `Ready`, `CoolingDown` ou `TemporarilyUnavailable` sans parser des erreurs ni connaître le fournisseur.
|
|
|
|
Les catégories existantes restent distinctes :
|
|
|
|
```text
|
|
AuthenticationUnavailable
|
|
CoolingDown
|
|
Disabled
|
|
Misconfigured
|
|
QuotaUnavailable
|
|
Ready
|
|
TemporarilyUnavailable
|
|
```
|
|
|
|
`pre.007` ne relie pas encore automatiquement les erreurs d'un refresh à ces transitions. Cette mutation runtime appartient au service de `pre.008`.
|
|
|
|
## 7. Façade publique
|
|
|
|
La taxonomie reste capability-scoped :
|
|
|
|
```text
|
|
MarketPriceBirdeye*
|
|
MarketPriceProviderRegistry*
|
|
MarketPriceProviderRequestCost
|
|
```
|
|
|
|
Aucun DTO wire Birdeye, `HttpRestClient`, limiter interne ou primitive `reqwest` n'est exporté.
|
|
|
|
Le registry public reste générique ; aucun consumer n'a besoin d'un enum CoinGecko/Birdeye/Jupiter pour l'inspecter.
|
|
|
|
## 8. Tests déterministes ajoutés
|
|
|
|
Les nouveaux canaries couvrent :
|
|
|
|
```text
|
|
Birdeye API key obligatoire si enabled
|
|
redaction du secret Birdeye
|
|
endpoint fixe et headers attendus
|
|
mint WSOL fixe
|
|
1 RPS par compte
|
|
30 000 compute units informatifs
|
|
3 compute units par Price Single
|
|
prix exact via RawValue
|
|
updateUnixTime -> provider_timestamp
|
|
success false rejeté
|
|
prix null rejeté
|
|
timestamp absent rejeté
|
|
request cost nul rejeté
|
|
mismatch unité quota/coût rejeté
|
|
registry des huit providers complet
|
|
ordre déterministe du registry
|
|
doublons provider_id rejetés
|
|
lookup descriptor/state générique
|
|
availability is_refresh_eligible/retry_at
|
|
absence de noms provider dans le module registry
|
|
```
|
|
|
|
## 9. Documentation réconciliée
|
|
|
|
Mise à jour de :
|
|
|
|
```text
|
|
docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md
|
|
docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md
|
|
```
|
|
|
|
Le plan enregistre le réaudit Birdeye courant et précise que quotas/cost metadata restent non-authoritative.
|
|
|
|
## 10. Fichiers ajoutés
|
|
|
|
```text
|
|
crates/ksp-offchain-transport-lib/src/market_price_birdeye.rs
|
|
crates/ksp-offchain-transport-lib/src/market_price_registry.rs
|
|
crates/ksp-offchain-transport-lib/unit_tests/market_price_birdeye.rs
|
|
crates/ksp-offchain-transport-lib/unit_tests/market_price_registry.rs
|
|
deltas/0.2.11/pre.007.md
|
|
```
|
|
|
|
## 11. Fichiers modifiés
|
|
|
|
```text
|
|
Cargo.toml
|
|
crates/ksp-offchain-transport-lib/src/error.rs
|
|
crates/ksp-offchain-transport-lib/src/lib.rs
|
|
crates/ksp-offchain-transport-lib/src/market_price_provider.rs
|
|
crates/ksp-offchain-transport-lib/tests/dependency_boundary.rs
|
|
crates/ksp-offchain-transport-lib/tests/public_api.rs
|
|
crates/ksp-offchain-transport-lib/unit_tests/market_price_provider.rs
|
|
docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md
|
|
docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md
|
|
```
|
|
|
|
## 12. Validation attendue
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
python3 scripts/audit_rust_workspace_rules.py
|
|
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.11
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
cargo test -p ksp-offchain-transport-lib
|
|
cargo test --workspace
|
|
```
|
|
|
|
`pre.008` ne doit commencer qu'après un gate propre de `pre.007` ou un delta fix explicite.
|