Files
khadhroony-bot3/olddocs/archivekbot2/kb_execution_solana/README.md
2026-07-30 17:50:29 +02:00

152 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- file: kb_execution_solana/README.md -->
<!-- version: 4 -->
# kb_execution_solana
`kb_execution_solana` transforme un `PreparedExecutionPlan` commun en message et transaction Solana, puis résout les signataires via linterface Solana `Signer` et signe uniquement après une simulation autorisée par `kb_execution_safety`.
La crate est indépendante des exécuteurs concrets et des transports RPC. Elle assemble aussi bien les plans à recent blockhash que les transactions consommant réellement un durable nonce.
## API publique
| Export | Usage |
|----------------------------------------|-------------------------------------------------------------------------------------------------------|
| `build_legacy_transaction(...)` | Compile un plan `Latest` avec un recent blockhash explicite. |
| `build_durable_nonce_transaction(...)` | Compile un plan `DurableNonce` avec un état nonce validé et injecte lavance en première instruction. |
| `durable_nonce_account_data_length()` | Fournit la longueur exacte à demander au RPC pour un compte nonce. |
| `parse_durable_nonce_account(...)` | Valide et décode un snapshot complet de compte nonce System. |
| `DurableNonceAccountState` | État validé exposant compte, autorité, nonce/blockhash et coût par signature. |
| `UnsignedSolanaTransaction` | Message compilé non signé, destiné aux frais, à la simulation exacte et à la signature contrôlée. |
| `SolanaSimulationEvidence` | Simulation liée au hash et au blockhash/nonce exacts du message. |
| `SignedSolanaTransaction` | Transaction signée, vérifiable localement et sérialisable pour `sendTransaction`. |
### Méthodes des types
| Type | Méthodes publiques |
|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `DurableNonceAccountState` | `account()`, `authority()`, `blockhash()`, `lamports_per_signature()`. |
| `UnsignedSolanaTransaction` | `plan()`, `message_hash()`, `blockhash()`, `required_signer_pubkeys()`, `message_base64()`, `transaction_base64()`, `bind_simulation(...)`, `sign_after_simulation(...)`. |
| `SolanaSimulationEvidence` | `message_hash()`, `blockhash()`, `simulation()`. |
| `SignedSolanaTransaction` | `message_hash()`, `primary_signature()`, `signer_pubkeys()`, `wire_length()`, `transaction_base64()`, `verify_signatures()`. |
## Exemple de flux
```rust
let unsigned = kb_execution_solana::build_legacy_transaction(&plan, recent_blockhash)?;
let simulation = rpc_simulation.to_execution_result(
unsigned.message_hash(),
unsigned.blockhash(),
observed_cluster,
)?;
let evidence = unsigned.bind_simulation(simulation)?;
let signed = unsigned.sign_after_simulation(&evidence, signers.as_slice())?;
signed.verify_signatures()?;
```
Le transport RPC reste extérieur : cette crate ne récupère pas le blockhash, ne charge pas le compte nonce et nenvoie pas le payload signé.
## Assemblage à recent blockhash
### `build_legacy_transaction(plan, recent_blockhash)`
Construit une transaction legacy non signée à partir dun blockhash base58 obtenu par `getLatestBlockhash`.
La fonction vérifie :
- la politique `ExecutionBlockhashKind::Latest` ;
- les public keys et le blockhash ;
- la présence dau moins une instruction ;
- légalité exacte entre signataires déclarés et signataires compilés ;
- la limite wire Solana de 1 232 octets.
Un plan `DurableNonce` est refusé et doit utiliser le chemin dédié.
## Lecture et validation dun compte nonce
### `durable_nonce_account_data_length()`
Retourne la taille wire officielle dun compte nonce, actuellement 80 octets. Cette valeur doit être utilisée comme limite exacte dun appel `getAccountInfo` avec données complètes.
### `parse_durable_nonce_account(account, owner, executable, space, data)`
Décode létat officiel `solana_nonce::versions::Versions` avec `wincode::deserialize_exact` et produit un `DurableNonceAccountState` uniquement lorsque toutes les conditions suivantes sont satisfaites :
- adresse du compte valide ;
- owner égal au System Program ;
- compte non exécutable ;
- `space` et longueur décodée égaux à la taille officielle ;
- version `Current` ;
- état `Initialized` ;
- autorité et valeur nonce extraites sans approximation.
Les états `Legacy`, `Uninitialized`, tronqués, suffixés ou possédés par un autre programme sont refusés. `DurableNonceAccountState` expose uniquement ladresse, lautorité, la valeur nonce utilisée comme blockhash et le coût par signature stocké dans létat.
Le chargement réseau reste extérieur à cette crate. Le contrat RPC prévu est :
```rust
let config = kb_rpc::GetAccountInfoConfig::confirmed_with_data(
kb_execution_solana::durable_nonce_account_data_length(),
)?;
```
## Assemblage durable nonce
### `build_durable_nonce_transaction(plan, nonce_state)`
Construit une transaction non signée qui consomme létat nonce validé.
La fonction exige :
- une politique `ExecutionBlockhashKind::DurableNonce` sans âge de blockhash récent ;
- le même compte nonce dans la politique et dans létat validé ;
- la même autorité dans la politique et dans létat validé ;
- lautorité nonce dans `required_signers` ;
- au moins une instruction métier à exécuter après lavance nonce.
Lassemblage utilise `Message::new_with_nonce`, place linstruction officielle `AdvanceNonceAccount` en position zéro, puis remplace le champ `recent_blockhash` par la valeur nonce extraite de létat. Le plan dorigine nest pas muté : `UnsignedSolanaTransaction::plan()` expose un plan effectif cloné contenant linstruction injectée.
Après compilation, la crate vérifie :
- la reconnaissance de la transaction par `solana_transaction::uses_durable_nonce` ;
- légalité exacte entre signataires déclarés et signataires compilés ;
- la taille wire ;
- le hash du message et la valeur nonce effectivement compilée.
Les opérations de gestion du compte nonce elles-mêmes, telles que `initialize`, `authorize`, `withdraw` ou `upgrade`, restent des transactions ordinaires à recent blockhash. Elles ne passent pas par ce chemin.
## Simulation et signature
### `UnsignedSolanaTransaction`
Expose :
- le plan effectif ;
- le hash exact du message ;
- le recent blockhash ou la valeur nonce compilée ;
- lordre exact des signataires ;
- le message base64 pour `getFeeForMessage` ;
- la transaction non signée base64 pour `simulateTransaction` avec `sigVerify = false` et `replaceRecentBlockhash = false`.
### `bind_simulation(result)`
Lie le résultat typé de simulation au hash du message **et** au blockhash/nonce compilé. Une simulation utilisant un autre message, une autre source de blockhash ou un blockhash de remplacement ne peut pas autoriser la signature.
### `sign_after_simulation(evidence, signers)`
Réévalue `kb_execution_safety`, exige une décision `Allow`, résout exactement tous les signataires via `&dyn solana_signer::Signer`, signe puis vérifie que la transaction est complète.
Les signataires manquants, supplémentaires ou dupliqués sont refusés. La fonction ne contacte aucun endpoint RPC et nenvoie rien.
### `SignedSolanaTransaction`
Expose uniquement des données non secrètes :
- hash du message ;
- signature primaire ;
- public keys des signataires ;
- taille wire ;
- payload base64 signé ;
- vérification locale des signatures.
Le payload signé reste côté backend. Il ne doit pas être transféré automatiquement à Tauri. `kb_rpc::HttpClient::send_transaction` et sa variante pool imposent le preflight et refusent une signature RPC différente de la signature primaire locale.