Files
khadhroony-solana-project/crates/ksp-raw-transaction-lib/USAGE.md
2026-09-09 11:44:36 +02:00

164 lines
7.3 KiB
Markdown

<!-- file: crates/ksp-raw-transaction-lib/USAGE.md -->
<!-- version: 2 -->
# Utilisation de ksp-raw-transaction-lib
Cette page décrit la façade publique durable de `ksp-raw-transaction-lib`. Les consumers utilisent uniquement les exports du crate-root.
## Parser une signature transactionnelle
Lorsqu'une source fournit une signature Base58 textuelle, la convertir avec le parser commun plutôt que de dupliquer le décodage :
```rust
fn parse_signature(value: &str) -> ksp_core_lib::Result<ksp_store_api::RawTransactionSignature> {
return ksp_raw_transaction_lib::parse_raw_transaction_signature(value);
}
```
Le résultat contient exactement 64 bytes canoniques. Les entrées vides, hors bornes, Base58 invalides ou de longueur décodée incorrecte sont rejetées sans recopier la valeur hostile dans l'erreur.
Lorsqu'un consumer possède déjà les 64 bytes canoniques et doit appeler une API textuelle Solana, utiliser l'encodeur commun plutôt que d'implémenter Base58 localement :
```rust
fn format_signature(value: &ksp_store_api::RawTransactionSignature) -> std::string::String {
return ksp_raw_transaction_lib::format_raw_transaction_signature(value);
}
```
Le texte produit respecte les bornes publiques de signature et effectue un round-trip exact avec `parse_raw_transaction_signature`.
Lorsqu'un wire Base64 complet contient déjà son tableau de signatures, utiliser :
```rust
fn embedded_signature(value: &str) -> ksp_core_lib::Result<ksp_store_api::RawTransactionSignature> {
return ksp_raw_transaction_lib::extract_raw_transaction_signature_from_binary_base64(value);
}
```
## Construire et sérialiser un wire Solana source-neutral
Le producer peut projeter son DTO Transport/protobuf vers les types `RawSolana*`, puis utiliser le sérialiseur commun. Exemple V1 minimal :
```rust
fn serialize_v1() -> ksp_core_lib::Result<std::string::String> {
let message = ksp_raw_transaction_lib::RawSolanaTransactionMessage::new(
ksp_raw_transaction_lib::RawSolanaMessageVersion::V1,
ksp_raw_transaction_lib::RawSolanaMessageHeader::new(1, 0, 0),
vec![[1_u8; 32]],
[2_u8; 32],
vec![ksp_raw_transaction_lib::RawSolanaCompiledInstruction::new(0, vec![0], vec![3])],
vec![],
std::option::Option::Some(ksp_raw_transaction_lib::RawSolanaTransactionConfig::default()),
);
let wire = ksp_raw_transaction_lib::RawSolanaTransactionWire::new(vec![[4_u8; 64]], message);
return ksp_raw_transaction_lib::serialize_solana_transaction_wire_base64(&wire);
}
```
Pour Legacy ou V0, choisir `RawSolanaMessageVersion::Legacy` ou `V0` et fournir uniquement les éléments admis par cette version. Le sérialiseur valide les invariants structurels avant de produire les bytes.
`RawSolanaAddressTableLookup` représente les lookups V0. `RawSolanaTransactionConfig` représente la configuration inline V1 ; le cas explicite où toutes ses options valent `None` reste sémantiquement présent.
## Construire le matériau RAW canonique
Une fois le wire transactionnel Base64 et les métadonnées source-neutral disponibles, construire `RawTransactionMaterial`. Les états wire doivent conserver la différence entre champ absent, `null` explicite et valeur :
```rust
fn material(
network: ksp_store_api::RawNetworkId,
signature: ksp_store_api::RawTransactionSignature,
transaction_base64: std::string::String,
) -> ksp_raw_transaction_lib::RawTransactionMaterial {
return ksp_raw_transaction_lib::RawTransactionMaterial::binary_base64(
network,
signature,
42,
std::option::Option::None,
transaction_base64,
ksp_raw_transaction_lib::RawTransactionWireField::Omitted,
ksp_raw_transaction_lib::RawTransactionWireField::Value(ksp_raw_transaction_lib::RawTransactionVersion::Legacy),
ksp_raw_transaction_lib::RawTransactionWireField::Omitted,
);
}
```
Pour une source où la signature doit être extraite du wire lui-même, `RawTransactionMaterial::binary_base64_with_embedded_signature` évite un second parser producer-owned.
## Canonicaliser vers RawTransaction
La canonicalisation est déterministe pour un même matériau complet :
```rust
fn canonicalize(
material: ksp_raw_transaction_lib::RawTransactionMaterial,
) -> ksp_core_lib::Result<ksp_store_api::RawTransaction> {
return ksp_raw_transaction_lib::canonicalize_raw_transaction(material);
}
```
La crate :
- canonicalise les sous-arbres JSON significatifs ;
- conserve les états omission / `null` / valeur ;
- construit le payload au format KSP RAW Transaction ;
- calcule son SHA-256 ;
- applique les bornes communes avant construction du modèle Store.
Elle ne persiste pas la transaction et ne choisit aucune politique de retry, endpoint ou source.
## Associer l'observation du producer
Le producer construit sa provenance avec les types Store API, puis assemble l'entité et l'observation :
```rust
fn acquisition(
transaction: ksp_store_api::RawTransaction,
) -> ksp_core_lib::Result<ksp_raw_transaction_lib::RawTransactionAcquisition> {
let provider = match ksp_store_api::RawProvenanceCode::new("example") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let protocol = match ksp_store_api::RawProvenanceCode::new("solana.http") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let method = match ksp_store_api::RawProvenanceCode::new("get_transaction") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let received_at = match ksp_store_api::RawTimestamp::from_unix_millis(1_700_000_000_000) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let provenance = ksp_store_api::RawAcquisitionProvenance::new(
provider,
protocol,
method,
ksp_store_api::RawAcquisitionOrigin::Live,
received_at,
);
return std::result::Result::Ok(ksp_raw_transaction_lib::assemble_raw_transaction_acquisition(
transaction,
ksp_store_api::RawObservationKey::new([7_u8; 32]),
provenance,
));
}
```
La clé d'observation doit être déterministe selon la politique du producer. Plusieurs sources peuvent produire des observations différentes pour la même identité canonique `(network, signature)`.
## Persister depuis un Job ou un Worker
La common crate ne dépend pas du Store runtime. Le lifecycle host concret récupère les deux parties puis appelle la façade Store appropriée :
```rust
let (transaction, observation) = acquisition.into_parts();
// Le Job/Worker concret transmet ensuite transaction + observation à ksp-store-lib.
```
Ne pas introduire `ksp-store-lib`, Transport, Config, Job ou Worker dans `ksp-raw-transaction-lib` pour simplifier cet appel. La direction de dépendance reste du producer vers la common RAW, puis du producer vers le Store runtime.
## Frontière avec STRUCTURAL
Ne pas utiliser cette crate pour décoder des Programs ou pour produire directement des unités STRUCTURAL. Son résultat reste D1 RAW. La décomposition `RAW -> STRUCTURAL` appartient à une couche ultérieure et réutilise le RAW durable comme input.