# 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 { 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 wire Base64 complet contient déjà son tableau de signatures, utiliser : ```rust fn embedded_signature(value: &str) -> ksp_core_lib::Result { 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 { 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 { 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 { 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.