v0.4.8-pre.007
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/OPERATION_NAMING_CONVENTION.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Convention canonique des identités runtime et des codes d’opération
|
||||
|
||||
@@ -82,6 +82,15 @@ kb-lib.materializer.transaction.annotations
|
||||
|
||||
Cette identité désigne le composant logiciel, pas une opération on-chain.
|
||||
|
||||
Pour un matérialisateur, le tracing target reprend exactement cette identité runtime. La paire avec le `processor_name` est déterministe :
|
||||
|
||||
```text
|
||||
component_name = kb-lib.<processor_name>
|
||||
processor_name = component_name sans le préfixe kb-lib.
|
||||
```
|
||||
|
||||
Les domaines spécialisés ne doivent pas être raccourcis : utiliser `compliance.audit`, `transaction.annotations` et `token.accounts`, et non les parents génériques `compliance`, `transaction` ou `token`.
|
||||
|
||||
### 3.2 `processor_name`
|
||||
|
||||
Format :
|
||||
@@ -265,4 +274,3 @@ Avant de fusionner une nouvelle opération :
|
||||
6. ajouter ou mettre à jour la matrice normative ;
|
||||
7. ajouter les tests de cohérence entre constantes et matrice ;
|
||||
8. vérifier l’impact PostgreSQL avant tout backfill ou replay durable.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/README.md -->
|
||||
<!-- version: 16 -->
|
||||
<!-- version: 18 -->
|
||||
|
||||
# Documentation active de Khadhroony Bot3
|
||||
|
||||
@@ -40,6 +40,8 @@ Modèles documentaires non génératifs :
|
||||
|
||||
- [`audits/V0_4_7_PRE_016_DOCUMENTATION_AND_HEADERS_AUDIT.md`](audits/V0_4_7_PRE_016_DOCUMENTATION_AND_HEADERS_AUDIT.md) ;
|
||||
- [`audits/V0_4_8_PRE_002_METADATA_CONTRACT_AUDIT.md`](audits/V0_4_8_PRE_002_METADATA_CONTRACT_AUDIT.md) ;
|
||||
- [`audits/V0_4_8_PRE_007_METAPLEX_MATERIALIZER_STRUCTURE_AUDIT.md`](audits/V0_4_8_PRE_007_METAPLEX_MATERIALIZER_STRUCTURE_AUDIT.md) ;
|
||||
- [`audits/V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md`](audits/V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md) ;
|
||||
- [`decisions/DOCUMENT_ARCHIVE_SELECTION_POLICY.md`](decisions/DOCUMENT_ARCHIVE_SELECTION_POLICY.md) ;
|
||||
- [`decisions/WINCODE_COMPATIBILITY_POLICY.md`](decisions/WINCODE_COMPATIBILITY_POLICY.md).
|
||||
|
||||
@@ -97,7 +99,9 @@ Les onze crates possèdent désormais `README.md`, `TODO.md`, `USAGE.md` et `CHA
|
||||
## Audits actifs
|
||||
|
||||
- [`Audit contractuel 0.4.8-pre.002 — metadata`](audits/V0_4_8_PRE_002_METADATA_CONTRACT_AUDIT.md) ;
|
||||
- [`Audit 0.4.8-pre.005 — instructions et historique Solana Program Metadata`](audits/V0_4_8_PRE_005_SOLANA_PROGRAM_METADATA_INSTRUCTION_HISTORY_AUDIT.md).
|
||||
- [`Audit 0.4.8-pre.005 — instructions et historique Solana Program Metadata`](audits/V0_4_8_PRE_005_SOLANA_PROGRAM_METADATA_INSTRUCTION_HISTORY_AUDIT.md) ;
|
||||
- [`Audit 0.4.8-pre.007 — structure du matérialiseur Metaplex Token Metadata`](audits/V0_4_8_PRE_007_METAPLEX_MATERIALIZER_STRUCTURE_AUDIT.md) ;
|
||||
- [`Audit 0.4.8-pre.007 — conventions et structure de tous les matérialisateurs`](audits/V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md).
|
||||
|
||||
## Plans de version actifs
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/audits/V0_4_8_PRE_002_METADATA_CONTRACT_AUDIT.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Audit contractuel `0.4.8-pre.002` — Solana Program Metadata et Token-2022
|
||||
|
||||
@@ -48,11 +48,11 @@ La structure, le Program ID, la version déclarée, les PDA, les comptes et les
|
||||
|
||||
### 4.1 PDA
|
||||
|
||||
| PDA | Seeds |
|
||||
|---|---|
|
||||
| canonical | `[program, seed]` |
|
||||
| non-canonical | `[program, authority, seed]` |
|
||||
| metadata | helper conditionnel sélectionnant l’une des deux dérivations selon la présence d’une autorité tierce |
|
||||
| PDA | Seeds |
|
||||
|---------------|------------------------------------------------------------------------------------------------------|
|
||||
| canonical | `[program, seed]` |
|
||||
| non-canonical | `[program, authority, seed]` |
|
||||
| metadata | helper conditionnel sélectionnant l’une des deux dérivations selon la présence d’une autorité tierce |
|
||||
|
||||
`seed` est une chaîne UTF-8 de taille fixe 16 octets dans l’IDL. Le code doit distinguer longueur en octets et nombre de caractères Unicode.
|
||||
|
||||
@@ -76,27 +76,27 @@ Ces valeurs décrivent uniquement les données on-chain. `Url` ne déclenche auc
|
||||
|
||||
### 4.4 Instructions
|
||||
|
||||
| Discriminant | Instruction | Comptes | Arguments |
|
||||
|---:|---|---|---|
|
||||
| `0` | `write` | `buffer` (writable)<br>`authority` (signer)<br>`sourceBuffer` (optional) | `offset: u32`<br>`data: Option<bytes>` |
|
||||
| `1` | `initialize` | `metadata` (writable)<br>`authority` (signer)<br>`program`<br>`programData` (optional)<br>`system` (optional) | `seed: Seed`<br>`encoding: Encoding`<br>`compression: Compression`<br>`format: Format`<br>`dataSource: DataSource`<br>`data: Option<bytes>` |
|
||||
| `2` | `setAuthority` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | `newAuthority: Option<pubkey>` |
|
||||
| `3` | `setData` | `metadata` (writable)<br>`authority` (signer)<br>`buffer` (writable, optional)<br>`program` (optional)<br>`programData` (optional) | `encoding: Encoding`<br>`compression: Compression`<br>`format: Format`<br>`dataSource: DataSource`<br>`data: Option<bytes>` |
|
||||
| `4` | `setImmutable` | `metadata` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | — |
|
||||
| `5` | `trim` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`destination` (writable)<br>`rent` | — |
|
||||
| `6` | `close` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`destination` (writable) | — |
|
||||
| `7` | `allocate` | `buffer` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`system` (optional) | `seed: Option<Seed>` |
|
||||
| `8` | `extend` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | `length: u16` |
|
||||
| Discriminant | Instruction | Comptes | Arguments |
|
||||
|-------------:|----------------|----------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `0` | `write` | `buffer` (writable)<br>`authority` (signer)<br>`sourceBuffer` (optional) | `offset: u32`<br>`data: Option<bytes>` |
|
||||
| `1` | `initialize` | `metadata` (writable)<br>`authority` (signer)<br>`program`<br>`programData` (optional)<br>`system` (optional) | `seed: Seed`<br>`encoding: Encoding`<br>`compression: Compression`<br>`format: Format`<br>`dataSource: DataSource`<br>`data: Option<bytes>` |
|
||||
| `2` | `setAuthority` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | `newAuthority: Option<pubkey>` |
|
||||
| `3` | `setData` | `metadata` (writable)<br>`authority` (signer)<br>`buffer` (writable, optional)<br>`program` (optional)<br>`programData` (optional) | `encoding: Encoding`<br>`compression: Compression`<br>`format: Format`<br>`dataSource: DataSource`<br>`data: Option<bytes>` |
|
||||
| `4` | `setImmutable` | `metadata` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | — |
|
||||
| `5` | `trim` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`destination` (writable)<br>`rent` | — |
|
||||
| `6` | `close` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`destination` (writable) | — |
|
||||
| `7` | `allocate` | `buffer` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`system` (optional) | `seed: Option<Seed>` |
|
||||
| `8` | `extend` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | `length: u16` |
|
||||
|
||||
### 4.5 Erreurs officielles
|
||||
|
||||
| Code | Erreur |
|
||||
|---:|---|
|
||||
| 0 | `NotExecutableAccount` |
|
||||
| 1 | `InvalidProgramState` |
|
||||
| 2 | `InvalidProgramDataAccount` |
|
||||
| 3 | `ImmutableMetadataAccount` |
|
||||
| 4 | `InvalidDataLength` |
|
||||
| Code | Erreur |
|
||||
|-----:|-----------------------------|
|
||||
| 0 | `NotExecutableAccount` |
|
||||
| 1 | `InvalidProgramState` |
|
||||
| 2 | `InvalidProgramDataAccount` |
|
||||
| 3 | `ImmutableMetadataAccount` |
|
||||
| 4 | `InvalidDataLength` |
|
||||
|
||||
## 5. Décisions de modèles et de validation `ProgM6…`
|
||||
|
||||
@@ -113,13 +113,13 @@ Ces valeurs décrivent uniquement les données on-chain. `Url` ne déclenche auc
|
||||
|
||||
## 6. Matrice de couverture Token-2022 réelle
|
||||
|
||||
| Capacité | Décodage wire | Intent public | Builder | Exécution | Lecture stateful | Matérialisation | Scénario dédié | Desktop | Devnet confirmé |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| `Initialize` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
|
||||
| `UpdateField` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
|
||||
| `RemoveKey` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
|
||||
| `UpdateAuthority` | oui | non | non | non | état extension lisible | extension observée | non | non | non |
|
||||
| `Emit` | oui | non | non | non | résultat de retour non orchestré | non dédiée | non | non | non |
|
||||
| Capacité | Décodage wire | Intent public | Builder | Exécution | Lecture stateful | Matérialisation | Scénario dédié | Desktop | Devnet confirmé |
|
||||
|-------------------|---------------|---------------|---------|----------------------------|----------------------------------|--------------------|----------------|-----------|-----------------|
|
||||
| `Initialize` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
|
||||
| `UpdateField` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
|
||||
| `RemoveKey` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
|
||||
| `UpdateAuthority` | oui | non | non | non | état extension lisible | extension observée | non | non | non |
|
||||
| `Emit` | oui | non | non | non | résultat de retour non orchestré | non dédiée | non | non | non |
|
||||
|
||||
Constats complémentaires :
|
||||
|
||||
|
||||
189
docs/audits/V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md
Normal file
189
docs/audits/V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md
Normal file
@@ -0,0 +1,189 @@
|
||||
<!-- file: docs/audits/V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Audit des conventions et de la structure des matérialisateurs — `0.4.8-pre.007-fix-004`
|
||||
|
||||
## 1. Objet
|
||||
|
||||
Cet audit couvre l’intégralité de `kb-lib/src/materializer` après l’activation du matérialisateur Solana Program Metadata et l’extraction des projections Metaplex Token Metadata et Token-2022.
|
||||
|
||||
Les contrôles portent sur :
|
||||
|
||||
- les identités runtime et les `processorName` persistés ;
|
||||
- les tracing targets ;
|
||||
- la structure des façades et sous-modules ;
|
||||
- l’emplacement, le nommage et la réexportation des constantes ;
|
||||
- les contrats communs `MtMaterializer` et `MtApiEventMaterializer` ;
|
||||
- la neutralité effective des matérialisateurs encore réservés ;
|
||||
- la provenance et les versions de projection des sorties actives.
|
||||
|
||||
## 2. Convention retenue
|
||||
|
||||
Chaque composant possède une paire d’identités issue de son `constants.rs` :
|
||||
|
||||
```text
|
||||
runtime component : kb-lib.materializer.<domain>[.<subsystem>]
|
||||
processorName : materializer.<domain>[.<subsystem>]
|
||||
```
|
||||
|
||||
Le `processorName` est exactement l’identité runtime privée du préfixe `kb-lib.`. Le tracing target d’un composant actif est identique à son identité runtime.
|
||||
|
||||
Exemples :
|
||||
|
||||
```text
|
||||
kb-lib.materializer.compliance.audit
|
||||
materializer.compliance.audit
|
||||
|
||||
kb-lib.materializer.transaction.annotations
|
||||
materializer.transaction.annotations
|
||||
|
||||
kb-lib.materializer.metadata.solana_program_metadata
|
||||
materializer.metadata.solana_program_metadata
|
||||
```
|
||||
|
||||
Les identités runtime servent au code et au routage des logs. Les `processorName` servent aux sorties persistées, au replay et à la provenance. Ils ne doivent pas être interchangeables.
|
||||
|
||||
## 3. Inventaire audité
|
||||
|
||||
| Composant | Type principal ou API | Statut | Identité runtime | `processorName` |
|
||||
|-------------------------|---------------------------------------|------------|--------------------------------------------------------|-------------------------------------------------|
|
||||
| Administration | `MtAdminMaterializer` | actif | `kb-lib.materializer.admin` | `materializer.admin` |
|
||||
| Bridge | `MtBridgeMaterializer` | réservé | `kb-lib.materializer.bridge` | `materializer.bridge` |
|
||||
| Compliance audit | `MtComplianceAuditMaterializer` | actif | `kb-lib.materializer.compliance.audit` | `materializer.compliance.audit` |
|
||||
| Fees | `MtFeesMaterializer` | actif | `kb-lib.materializer.fees` | `materializer.fees` |
|
||||
| Governance | `MtGovernanceMaterializer` | réservé | `kb-lib.materializer.governance` | `materializer.governance` |
|
||||
| Lending | `MtLendingMaterializer` | réservé | `kb-lib.materializer.lending` | `materializer.lending` |
|
||||
| Lifecycle | `MtLifecycleMaterializer` | actif | `kb-lib.materializer.lifecycle` | `materializer.lifecycle` |
|
||||
| Liquidity | `MtLiquidityMaterializer` | réservé | `kb-lib.materializer.liquidity` | `materializer.liquidity` |
|
||||
| Metaplex Token Metadata | APIs de snapshots | state-only | `kb-lib.materializer.metadata.metaplex_token_metadata` | `materializer.metadata.metaplex_token_metadata` |
|
||||
| Solana Program Metadata | `MtSolanaProgramMetadataMaterializer` | actif | `kb-lib.materializer.metadata.solana_program_metadata` | `materializer.metadata.solana_program_metadata` |
|
||||
| Token-2022 metadata | API de snapshots | state-only | `kb-lib.materializer.metadata.token_2022` | `materializer.metadata.token_2022` |
|
||||
| NFT | `MtNftMaterializer` | réservé | `kb-lib.materializer.nft` | `materializer.nft` |
|
||||
| Oracle | `MtOracleMaterializer` | réservé | `kb-lib.materializer.oracle` | `materializer.oracle` |
|
||||
| Orderbook | `MtOrderbookMaterializer` | réservé | `kb-lib.materializer.orderbook` | `materializer.orderbook` |
|
||||
| Perpetuals | `MtPerpetualsMaterializer` | réservé | `kb-lib.materializer.perpetuals` | `materializer.perpetuals` |
|
||||
| Pool state | `MtPoolStateMaterializer` | réservé | `kb-lib.materializer.pool.state` | `materializer.pool.state` |
|
||||
| Rewards | `MtRewardsMaterializer` | réservé | `kb-lib.materializer.rewards` | `materializer.rewards` |
|
||||
| Risk | `MtRiskMaterializer` | actif | `kb-lib.materializer.risk` | `materializer.risk` |
|
||||
| Routing | `MtRoutingMaterializer` | réservé | `kb-lib.materializer.routing` | `materializer.routing` |
|
||||
| Staking | `MtStakingMaterializer` | actif | `kb-lib.materializer.staking` | `materializer.staking` |
|
||||
| Token accounts | `MtTokenAccountsMaterializer` | actif | `kb-lib.materializer.token.accounts` | `materializer.token.accounts` |
|
||||
| Token metadata risk | `MtTokenMetadataRiskMaterializer` | réservé | `kb-lib.materializer.token.metadata_risk` | `materializer.token.metadata_risk` |
|
||||
| Trades | `MtTradesMaterializer` | réservé | `kb-lib.materializer.trades` | `materializer.trades` |
|
||||
| Transaction annotations | `MtTransactionAnnotationMaterializer` | actif | `kb-lib.materializer.transaction.annotations` | `materializer.transaction.annotations` |
|
||||
| Vault | `MtVaultMaterializer` | réservé | `kb-lib.materializer.vault` | `materializer.vault` |
|
||||
|
||||
Bilan : **25 composants nommés**, dont **9 matérialisateurs actifs**, **14 coquilles réservées** et **2 composants state-only**.
|
||||
|
||||
`MtMetadataMaterializer` reste un wrapper public de compatibilité vers `MtSolanaProgramMetadataMaterializer`. Il ne possède pas une identité distincte et ne crée pas un second propriétaire de projection.
|
||||
|
||||
## 4. Structure normalisée
|
||||
|
||||
Un matérialisateur simple suit désormais la structure :
|
||||
|
||||
```text
|
||||
<component>.rs
|
||||
<component>/constants.rs
|
||||
<component>/materializer.rs
|
||||
```
|
||||
|
||||
La façade `<component>.rs` ne contient que les déclarations de sous-modules et leurs réexports. Les composants complexes peuvent ajouter des fichiers spécialisés, par exemple `state.rs` ou `account.rs`, sans placer d’implémentation dans la façade.
|
||||
|
||||
Les domaines imbriqués suivent la même règle :
|
||||
|
||||
```text
|
||||
compliance/audit.rs
|
||||
compliance/audit/constants.rs
|
||||
compliance/audit/materializer.rs
|
||||
|
||||
transaction/annotations.rs
|
||||
transaction/annotations/constants.rs
|
||||
transaction/annotations/materializer.rs
|
||||
```
|
||||
|
||||
Les anciens noms génériques `core.rs` ont été remplacés par `materializer.rs`. Les tables de surfaces, familles acceptées, identités, versions de projection et tracing targets résident dans les `constants.rs`, sont réexportées jusqu’à `kb-lib/src/lib.rs` et sont consommées via `crate::`.
|
||||
|
||||
## 5. Coquilles réservées
|
||||
|
||||
Une coquille réservée doit :
|
||||
|
||||
- conserver son type public `Mt*Materializer` ;
|
||||
- implémenter les deux traits communs ;
|
||||
- exposer une constante `MT_*_ACCEPTED_FAMILIES` vide ;
|
||||
- retourner `false` depuis l’ancien `accepts_event` ;
|
||||
- retourner une liste vide depuis l’ancien `materialize_event` ;
|
||||
- retourner `Ignored` depuis le contrat contextuel ;
|
||||
- ne produire aucun événement, aucune sortie et aucune provenance fictive.
|
||||
|
||||
Le comportement antérieur qui pouvait retourner un événement legacy malgré une frontière inactive a été supprimé.
|
||||
|
||||
## 6. Provenance et versionnement
|
||||
|
||||
Les sorties actives utilisent uniquement leur constante `MT_*_PROCESSOR_NAME`. Aucun `processorName` littéral ne reste dans les implémentations.
|
||||
|
||||
Les changements de provenance Metaplex et Token-2022 livrés dans `fix-002` restent associés à `projectionVersion = 2`. Solana Program Metadata conserve `projectionVersion = 1`, car sa projection est introduite dans `0.4.8`.
|
||||
|
||||
L’ajout d’une provenance explicite aux sorties qui ne possédaient encore qu’une version numérique modifie leur contrat persisté. Les matérialisateurs `admin`, `compliance.audit`, `fees`, `lifecycle` et `staking` passent donc de `projectionVersion = 1` à `projectionVersion = 2`. Les matérialisateurs `risk`, `token.accounts` et `transaction.annotations` conservaient déjà une provenance spécialisée et gardent leurs versions existantes.
|
||||
|
||||
Les `output_key` et les familles métier existantes ne sont pas renommées par cet audit.
|
||||
|
||||
## 7. Configuration de logging
|
||||
|
||||
Les routes de `config/example.config.json` sont alignées sur les tracing targets spécialisés :
|
||||
|
||||
```text
|
||||
kb-lib.materializer.compliance.audit
|
||||
kb-lib.materializer.transaction.annotations
|
||||
kb-lib.materializer.token.accounts
|
||||
```
|
||||
|
||||
Les noms de sinks et leurs chemins sont harmonisés avec les mêmes sous-domaines.
|
||||
|
||||
## 8. Garde-fous ajoutés
|
||||
|
||||
L’audit mécanique du workspace vérifie désormais :
|
||||
|
||||
- la paire obligatoire `MT_*_COMPONENT_NAME` / `MT_*_PROCESSOR_NAME` ;
|
||||
- la relation exacte obtenue par suppression du préfixe `kb-lib.` ;
|
||||
- l’absence de constantes hors `constants.rs` ;
|
||||
- la présence d’un `constants.rs` à côté de chaque implémentation ;
|
||||
- l’absence d’identités littérales dans les implémentations ;
|
||||
- la présence conjointe de `projectionVersion` et `processorName` dans chaque payload versionné ;
|
||||
- l’utilisation obligatoire des constantes `MT_*_PROJECTION_VERSION` et `MT_*_PROCESSOR_NAME` dans ces payloads ;
|
||||
- la pureté des façades ;
|
||||
- le résultat vide des deux contrats d’une coquille réservée.
|
||||
|
||||
Les tests Rust conservent en plus l’inventaire typé des matérialisateurs et contrôlent la convention de nommage.
|
||||
|
||||
## 9. Fichiers obsolètes à supprimer
|
||||
|
||||
Les 22 chemins retirés sont fournis dans `delete-files.txt` à la racine du delta. Leur suppression est obligatoire avant la validation, car une extraction ZIP ne peut pas retirer les anciens fichiers.
|
||||
|
||||
## 10. Conclusion
|
||||
|
||||
Les matérialisateurs utilisent désormais une convention unique pour les identités runtime, les processeurs persistés, les tracing targets, les constantes, les façades et les coquilles réservées. Les différences restantes sont fonctionnelles et explicites : un composant peut être actif, réservé ou state-only, mais il ne change pas de convention structurelle ou de provenance selon son statut.
|
||||
|
||||
## 11. Correction des identités opérationnelles et du tracing
|
||||
|
||||
La compilation du workspace corrigé a révélé trois tracing targets déclarés mais sans événement réel :
|
||||
|
||||
- `kb-lib.materializer.fees` ;
|
||||
- `kb-lib.materializer.metadata.metaplex_token_metadata` ;
|
||||
- `kb-lib.materializer.metadata.token_2022`.
|
||||
|
||||
Le composant state-only Token-2022 réexportait également `MT_METADATA_TOKEN_2022_COMPONENT_NAME` sans le consommer dans son implémentation. Cette situation ne signifiait pas que les snapshots Token-2022 n’étaient pas matérialisés : la fonction `materializer_metadata_materialize_token_2022_snapshot` produisait déjà les projections `TokenMetadata`, `TokenGroup` et `TokenGroupMember`. Elle révélait en revanche que l’identité runtime du composant n’était pas attachée à une opération observable.
|
||||
|
||||
Le correctif ajoute des événements structurés réels pour les chemins suivants :
|
||||
|
||||
- observation et snapshots de frais Token-2022 ;
|
||||
- snapshots de comptes Metaplex et `MetadataV1` ;
|
||||
- snapshots metadata, group et group-member Token-2022.
|
||||
|
||||
Les événements portent le tracing target du composant, son `component_name`, son `processor_name`, sa version, le statut et les identités disponibles. Aucun faux `let _target` n’est utilisé et aucun champ persistant n’est ajouté uniquement pour supprimer un warning.
|
||||
|
||||
L’audit mécanique refuse désormais :
|
||||
|
||||
- un `TRACING_TARGET_*` de `kb-lib` déclaré sans macro `tracing` réelle ;
|
||||
- un `MT_*_COMPONENT_NAME` qui n’est consommé par aucun fichier d’implémentation du composant.
|
||||
|
||||
Les composants state-only restent distincts des matérialiseurs instructionnels : ils n’implémentent pas artificiellement `MtApiEventMaterializer`, mais leur identité runtime est désormais effectivement utilisée par leurs opérations de snapshot.
|
||||
@@ -0,0 +1,109 @@
|
||||
<!-- file: docs/audits/V0_4_8_PRE_007_METAPLEX_MATERIALIZER_STRUCTURE_AUDIT.md -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# Audit `0.4.8-pre.007` — structure et identités des matérialiseurs metadata
|
||||
|
||||
## 1. Questions vérifiées
|
||||
|
||||
Deux ambiguïtés structurelles ont été vérifiées :
|
||||
|
||||
- l’absence initiale d’un sous-module dédié à Metaplex Token Metadata ;
|
||||
- l’emplacement et la couverture de la matérialisation Token-2022 Token Metadata.
|
||||
|
||||
L’audit a également séparé l’identité runtime d’un composant de son `processorName` persisté.
|
||||
|
||||
## 2. Metaplex Token Metadata
|
||||
|
||||
Il n’existait pas d’oubli fonctionnel en `0.4.7`. Les APIs publiques suivantes étaient déjà implémentées :
|
||||
|
||||
- `materializer_metadata_materialize_metaplex_metadata_snapshot` pour l’état autoritatif `MetadataV1` ;
|
||||
- `materializer_metadata_materialize_metaplex_account_snapshot` pour les autres comptes Metaplex canoniques matérialisables.
|
||||
|
||||
Le défaut était structurel : ces fonctions partageaient auparavant `metadata/core.rs` avec d’autres domaines. Elles sont désormais isolées dans :
|
||||
|
||||
```text
|
||||
kb-lib/src/materializer/metadata/metaplex_token_metadata.rs
|
||||
kb-lib/src/materializer/metadata/metaplex_token_metadata/constants.rs
|
||||
kb-lib/src/materializer/metadata/metaplex_token_metadata/state.rs
|
||||
kb-lib/src/materializer/metadata/metaplex_token_metadata/account.rs
|
||||
```
|
||||
|
||||
Les clés de sortie et la sémantique métier restent inchangées. La provenance utilise désormais le `processorName` dédié :
|
||||
|
||||
```text
|
||||
materializer.metadata.metaplex_token_metadata
|
||||
```
|
||||
|
||||
Comme cette valeur persistée change par rapport au contrat antérieur, `projectionVersion` passe de `1` à `2`.
|
||||
|
||||
## 3. Token-2022 Token Metadata
|
||||
|
||||
Les états Token-2022 étaient déjà matérialisés par :
|
||||
|
||||
```text
|
||||
materializer_metadata_materialize_token_2022_snapshot
|
||||
```
|
||||
|
||||
Cette fonction projette les extensions de mint suivantes :
|
||||
|
||||
- `TokenMetadata` ;
|
||||
- `TokenGroup` ;
|
||||
- `TokenGroupMember`.
|
||||
|
||||
Elle était cependant placée dans `metadata/core.rs`. Le correctif l’extrait vers :
|
||||
|
||||
```text
|
||||
kb-lib/src/materializer/metadata/token_2022.rs
|
||||
kb-lib/src/materializer/metadata/token_2022/constants.rs
|
||||
kb-lib/src/materializer/metadata/token_2022/state.rs
|
||||
```
|
||||
|
||||
La fonction publique et les `output_key` restent inchangées. Sa provenance utilise :
|
||||
|
||||
```text
|
||||
materializer.metadata.token_2022
|
||||
```
|
||||
|
||||
Le schéma de projection passe à `2` pour refléter cette correction d’identité.
|
||||
|
||||
## 4. Écart fonctionnel Token-2022 restant
|
||||
|
||||
La matérialisation d’état ne couvre pas à elle seule toutes les observations décodées.
|
||||
|
||||
Les faits `InitializeMetadataPointer` et `UpdateMetadataPointer` sont déjà possédés par le matérialiseur d’administration. En revanche, les cinq observations de `spl-token-metadata-interface` ne disposent pas encore d’une matérialisation d’instruction dédiée :
|
||||
|
||||
- `Initialize` ;
|
||||
- `UpdateField` ;
|
||||
- `RemoveKey` ;
|
||||
- `UpdateAuthority` ;
|
||||
- `Emit`.
|
||||
|
||||
Cet écart doit être fermé dans `0.4.8-pre.010`, en même temps que la complétude des intents, builders, lectures avant/après et postconditions Token-2022.
|
||||
|
||||
## 5. Solana Program Metadata
|
||||
|
||||
L’identité runtime du composant reste :
|
||||
|
||||
```text
|
||||
kb-lib.materializer.metadata.solana_program_metadata
|
||||
```
|
||||
|
||||
Le `processorName` persistant du composant Solana Program Metadata est corrigé en :
|
||||
|
||||
```text
|
||||
materializer.metadata.solana_program_metadata
|
||||
```
|
||||
|
||||
Le tracing target reste distinct et conserve son préfixe runtime :
|
||||
|
||||
```text
|
||||
kb-lib.materializer.metadata.solana_program_metadata
|
||||
```
|
||||
|
||||
## 6. Conséquence de migration
|
||||
|
||||
Les projections dérivées Metaplex et Token-2022 produites avec les anciennes provenances doivent être reconstruites depuis les raws ou migrées si elles sont conservées. Les clés de sortie ne changent pas.
|
||||
|
||||
## 7. Conclusion
|
||||
|
||||
Metaplex et les états metadata Token-2022 étaient déjà matérialisés. `pre.007-fix-002` corrige leurs identités et leur organisation modulaire. `pre.007-fix-003` étend ensuite la même convention à l’intégralité des matérialisateurs ; voir `V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md`. La seule lacune fonctionnelle confirmée concerne les cinq faits d’instructions `spl-token-metadata-interface`, explicitement reportés à `pre.010`.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/guides/LOGGING.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Guide de logging et tracing
|
||||
|
||||
@@ -50,8 +50,13 @@ kb-pipeline.backfill
|
||||
kb-pipeline.decode-replay
|
||||
kb-onchain-transport.http
|
||||
kb-lib.executor.spl.token-2022
|
||||
kb-lib.materializer.compliance.audit
|
||||
kb-lib.materializer.token.accounts
|
||||
kb-lib.materializer.transaction.annotations
|
||||
```
|
||||
|
||||
Pour un matérialisateur, la target de tracing est l’identité runtime `kb-lib.materializer.<domain>[.<subsystem>]`. Elle reste distincte du `processorName` persisté `materializer.<domain>[.<subsystem>]`, qui ne doit pas être utilisé comme target de logs.
|
||||
|
||||
Une nouvelle target doit être ajoutée selon `docs/OPERATION_NAMING_CONVENTION.md` et les règles Khadhroony.
|
||||
|
||||
## Frontend desktop
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- file: docs/plans/V0_4_8_SOLANA_PROGRAM_METADATA_AND_TOKEN_2022_COMPLETENESS_PLAN.md -->
|
||||
<!-- version: 7 -->
|
||||
<!-- version: 10 -->
|
||||
|
||||
# Plan `0.4.8` — Solana Program Metadata et complétude Token-2022
|
||||
|
||||
## 1. Statut et rôle
|
||||
|
||||
Ce document est le livrable principal de `0.4.8-pre.001`, réconcilié après l’audit contractuel de `0.4.8-pre.002`, les modèles de `pre.003`, les décodeurs de comptes de `pre.004`, le décodeur d’instructions de `pre.005` et la matérialisation de `pre.006`. Il constitue le plan vivant de la version et reste modifiable lorsque l’audit du code, des interfaces officielles, de l’IDL ou des validations Devnet impose un ajustement.
|
||||
Ce document est le livrable principal de `0.4.8-pre.001`, réconcilié après l’audit contractuel de `0.4.8-pre.002`, les modèles de `pre.003`, les décodeurs de comptes de `pre.004`, le décodeur d’instructions de `pre.005`, la matérialisation de `pre.006` et l’exécuteur de `pre.007`. Il constitue le plan vivant de la version et reste modifiable lorsque l’audit du code, des interfaces officielles, de l’IDL ou des validations Devnet impose un ajustement.
|
||||
|
||||
Il doit être maintenu pendant chaque prerelease, puis archivé pendant la dernière prerelease après transfert des décisions durables vers le ROADMAP, les matrices, les guides, les rapports, les TODO et les changelogs concernés.
|
||||
|
||||
@@ -15,13 +15,13 @@ Il doit être maintenu pendant chaque prerelease, puis archivé pendant la derni
|
||||
|
||||
### 2.1 Surfaces strictement distinctes
|
||||
|
||||
| Surface | Program ID ou frontière | Rôle dans `0.4.8` |
|
||||
|---|---|---|
|
||||
| Metaplex Token Metadata | `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s` | surface clôturée en `0.4.7`, hors développement principal |
|
||||
| Token-2022 Token Metadata | programme Token-2022 `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` | compléter le contrat déjà partiellement pris en charge |
|
||||
| `spl-token-metadata-interface` | interface sans Program ID autonome imposé | source contractuelle des instructions metadata implémentées par Token-2022 |
|
||||
| Solana Program Metadata | `ProgM6JCCvbYkfKqJYHePx4xxSUSqJp7rh8Lyv7nk7S` | nouvelle surface on-chain à implémenter sous `metadata/solana_program_metadata` |
|
||||
| contenu distant HTTP/IPFS/Arweave | transport off-chain indépendant | hors `0.4.8`, reporté à l’horizon `0.15+` |
|
||||
| Surface | Program ID ou frontière | Rôle dans `0.4.8` |
|
||||
|-----------------------------------|--------------------------------------------------------------------|---------------------------------------------------------------------------------|
|
||||
| Metaplex Token Metadata | `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s` | surface clôturée en `0.4.7`, hors développement principal |
|
||||
| Token-2022 Token Metadata | programme Token-2022 `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` | compléter le contrat déjà partiellement pris en charge |
|
||||
| `spl-token-metadata-interface` | interface sans Program ID autonome imposé | source contractuelle des instructions metadata implémentées par Token-2022 |
|
||||
| Solana Program Metadata | `ProgM6JCCvbYkfKqJYHePx4xxSUSqJp7rh8Lyv7nk7S` | nouvelle surface on-chain à implémenter sous `metadata/solana_program_metadata` |
|
||||
| contenu distant HTTP/IPFS/Arweave | transport off-chain indépendant | hors `0.4.8`, reporté à l’horizon `0.15+` |
|
||||
|
||||
Aucun décodeur Token-2022 existant n’est un décodeur partiel de `ProgM6…`. Les deux contrats doivent conserver des namespaces, modèles, matrices, tests et scénarios distincts.
|
||||
|
||||
@@ -259,16 +259,22 @@ Résultat durable : les deux comptes décodés et les neuf instructions stables
|
||||
- matrice de onze projections et test de façade externe ;
|
||||
- aucune résolution de contenu distant ni lecture implicite d’un compte externe.
|
||||
|
||||
Critère atteint côté delta : tout ce qui est décodé dans la surface `ProgM6…` est matérialisable. Compilation, Clippy et tests Rust restent à exécuter dans l’environnement du projet avant validation définitive.
|
||||
Validation définitive reçue le 5 août 2026 : `cargo fmt --all`, `cargo check --workspace`, `cargo clippy --all-targets` et l’audit workspace sont propres ; `cargo test -p kb-lib` réussit avec 667 tests unitaires, les tests d’API externes et les doc-tests.
|
||||
|
||||
### `0.4.8-pre.007` — builders et exécuteur Solana Program Metadata
|
||||
### `0.4.8-pre.007` — builders et exécuteur Solana Program Metadata — terminé côté delta
|
||||
|
||||
- PDA, calculs de taille et rent ;
|
||||
- builders contractuellement équivalents pour toutes les opérations courantes, y compris les mutations destructrices, irréversibles ou écrasantes ;
|
||||
- politiques de signataires, autorités, coûts, confirmations, postconditions et capacités ;
|
||||
- intégration explicite au cadre commun `crate::ExSafetyChecker` : le builder expose le plan complet, tandis que la politique de sécurité décide si ce plan peut progresser vers la simulation, la signature et l’envoi ;
|
||||
- classification opérationnelle conforme aux règles : opérations courantes exécutables, opérations officiellement obsolètes annotées `#[deprecated]` avec approbation explicite, versions officiellement remplacées conservées en decode-only ;
|
||||
- état audit actuel : les neuf instructions stables `0..8` sont courantes, sans instruction remplacée ou obsolète, donc toutes les neuf doivent être ciblées par l’exécuteur sauf découverte officielle contraire documentée avant code.
|
||||
Résultat durable : les neuf instructions stables possèdent une opération typée, un builder wire exact et une capacité d’exécution. Les mutations dangereuses restent constructibles mais exigent une approbation explicite ; tous les plans traversent `ExSafetyChecker` avant d’être remis à l’orchestration.
|
||||
|
||||
- helpers de PDA canonical et non-canonical avec seed exact de 16 octets ;
|
||||
- sélection de canonicité explicite dans l’intent, indépendante de la seule présence de `ProgramData` ;
|
||||
- builders des neuf opérations, comptes positionnels, signataires et variantes inline/Buffer ;
|
||||
- simulation et quatre postconditions obligatoires ;
|
||||
- approbation explicite pour `Write`, `SetAuthority`, `SetData`, `SetImmutable`, `Trim` et `Close` ;
|
||||
- matrice d’exécution et test d’API externe ;
|
||||
- aucune opération stable classée deprecated ou replaced faute de preuve officielle ;
|
||||
- financement de rent volontairement laissé à la fixture et à l’orchestration RPC : le programme exige que les comptes à allouer ou étendre soient préfinancés.
|
||||
|
||||
Travaux parallèles intégrés : les fonctions de matérialisation Metaplex existaient déjà dans `materializer/metadata/core.rs`; il ne s’agissait donc pas d’un oubli fonctionnel de `0.4.6/0.4.7`. Elles sont déplacées dans un sous-module dédié sans changement de clé métier. Token-2022 reçoit également son composant state-only dédié. L’audit est ensuite étendu à l’ensemble de `src/materializer` : 25 identités sont harmonisées, les façades deviennent pures, les implémentations utilisent `materializer.rs`, les constantes sont centralisées et les coquilles réservées ne produisent plus de faux événements legacy. Les constats sont consignés dans `docs/audits/V0_4_8_PRE_007_METAPLEX_MATERIALIZER_STRUCTURE_AUDIT.md` et `docs/audits/V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md`. Un audit transversal de toutes les surfaces déjà livrées est planifié en `0.5.x` pour vérifier les règles de décodage exhaustif, propriété de matérialisation, exécution des opérations dangereuses via `ExSafetyChecker`, dépréciation officielle et versions remplacées decode-only.
|
||||
|
||||
### `0.4.8-pre.008` — pipeline stateful Solana Program Metadata
|
||||
|
||||
@@ -283,6 +289,9 @@ Critère atteint côté delta : tout ce qui est décodé dans la surface `ProgM6
|
||||
### `0.4.8-pre.010` — complétude Token-2022 Token Metadata
|
||||
|
||||
- implémentation des écarts confirmés de `Initialize`, `UpdateField`, `RemoveKey`, `UpdateAuthority` et `Emit` ;
|
||||
- conservation du matérialiseur d’état dédié `metadata/token_2022/` pour les extensions `TokenMetadata`, `TokenGroup` et `TokenGroupMember` ;
|
||||
- ajout d’une matérialisation explicite des cinq observations d’instructions `spl-token-metadata-interface`, actuellement absente ;
|
||||
- maintien de `InitializeMetadataPointer` et `UpdateMetadataPointer` dans le matérialiseur d’administration qui en possède déjà les faits ;
|
||||
- tests synthétiques et stateful.
|
||||
|
||||
### `0.4.8-pre.011` — campagne Devnet Token-2022 Token Metadata
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/RULES_SPECIFIC_KHADHROONY.md -->
|
||||
<!-- version: 8 -->
|
||||
<!-- version: 10 -->
|
||||
|
||||
# Règles spécifiques à `khadhroony-bot3`
|
||||
|
||||
@@ -53,6 +53,13 @@ Toute divergence avec une règle générale doit être explicitement documentée
|
||||
- Une même réalité métier doit avoir une seule projection canonique. Les snapshots de comptes sont la source autoritative de l'état final lorsqu'ils sont disponibles ; les instructions et événements corrélés restent des observations de mutation et ne doivent pas produire un doublon concurrent du même état.
|
||||
- Les matérialisateurs doivent refuser les transactions non commitées pour les mutations d'état, tout en pouvant conserver séparément une intention non commitée lorsque le modèle métier le prévoit explicitement.
|
||||
- Toute absence volontaire de projection doit être documentée avec une justification technique précise. Un matérialisateur ne doit inventer ni état final, ni montant, ni autorité, ni frais, ni agrégation que l'observation ne prouve pas.
|
||||
- Chaque matérialisateur concret possède un composant structuré avec une façade limitée aux déclarations de sous-modules et réexports, un `constants.rs` et un `materializer.rs`. Les fichiers spécialisés `state.rs`, `account.rs` ou équivalents sont ajoutés seulement lorsque leur responsabilité est distincte.
|
||||
- L’identité runtime suit `kb-lib.materializer.<domain>[.<subsystem>]`. Le `processorName` persisté suit `materializer.<domain>[.<subsystem>]` et doit être exactement l’identité runtime sans le préfixe `kb-lib.`. Le tracing target d’un composant actif est identique à son identité runtime.
|
||||
- Les constantes d’un composant utilisent le préfixe `MT_<COMPONENT>_`, résident dans son `constants.rs`, sont réexportées par chaque façade jusqu’à `kb-lib/src/lib.rs` et sont consommées par `crate::`, y compris dans les tests lorsqu’elles sont `pub` ou `pub(crate)`.
|
||||
- Toute sortie persistée contient un `processorName` issu de la constante du composant et une `projectionVersion` explicite. Une correction de provenance persistée impose une nouvelle version de projection.
|
||||
- Une coquille réservée implémente `MtMaterializer` et `MtApiEventMaterializer`, expose une constante `MT_*_ACCEPTED_FAMILIES` vide, refuse tous les événements, retourne une liste legacy vide et un résultat contextuel `Ignored`. Elle ne doit jamais créer un faux événement de transition.
|
||||
- Un composant state-only peut exposer uniquement des APIs de snapshots sans implémenter `MtApiEventMaterializer`; ce statut doit être explicite et ne crée pas artificiellement un matérialisateur instructionnel.
|
||||
- Un wrapper public de compatibilité délègue vers le composant canonique et conserve exactement la même identité. Il ne constitue pas un second propriétaire de faits.
|
||||
|
||||
### Couverture des exécuteurs
|
||||
|
||||
@@ -178,7 +185,7 @@ Aucun renommage massif de modules n'est autorisé sans étape de contrôle dédi
|
||||
- Les targets historiques `khbot.*` et les targets de fenêtre sont interdits dans les nouvelles modifications.
|
||||
- Les macros `tracing` doivent utiliser `target: crate::TRACING_TARGET` et des champs structurés stables. La granularité interne passe par `action`, `stage`, `window`, `campaign_id`, `signature`, `instruction_path`, `program_id`, `processor_name`, `processor_version`, `status` et `error_code`.
|
||||
- Les crates passives de types, contrats, DTO, API sans exécution, registres ou constantes restent sans dépendance `tracing`. `kb-config` reste une exception de bootstrap tant que sa validation précède l’installation du subscriber.
|
||||
- Il est interdit d’ajouter `tracing` sans événement réel ou de conserver un faux target uniquement consommé par `let _target`.
|
||||
- Il est interdit d’ajouter `tracing` sans événement réel, de conserver un tracing target déclaré mais inutilisé ou de consommer artificiellement un target avec `let _target`.
|
||||
- Une décision interne doit être journalisée par la crate responsable ; `kb-app-demo-desktop` ne journalise que les frontières Tauri/UI, les actions utilisateur et les résumés d’orchestration.
|
||||
- Tout input sélectionné sans décodeur compatible, tout résultat de décodage `failed` ou `unsupported`, tout résultat de matérialisation `failed`, toute validation de résultat invalide et toute erreur de persistance doivent émettre un événement `error` avant le retour ou la persistance terminale.
|
||||
- Une transaction Solana échouée mais correctement décodée n’est pas une erreur du logiciel. Une décision `ignored`, un refus de matérialisation conforme à la politique ou une annulation coopérative ne doivent pas être promus artificiellement au niveau `error`.
|
||||
@@ -187,7 +194,7 @@ Aucun renommage massif de modules n'est autorisé sans étape de contrôle dédi
|
||||
- Chaque profil doit router les événements vers les sorties globales `debug.log`, `info.log`, `error.jsonl` et `app.log`, puis vers `debug.log`, `info.log` et `error.jsonl` dans un répertoire propre à chaque crate utilisant `tracing`.
|
||||
- L’ajout ou la suppression de `tracing.workspace = true` dans une crate impose la mise à jour simultanée de la matrice de routes, de ses tests et de `docs/TRACING_CONTRACT.md`.
|
||||
- Le contrat détaillé est défini dans `docs/TRACING_CONTRACT.md`.
|
||||
- L’audit mécanique spécifique au projet est exécuté par `python3 scripts/audit_khadhroony_workspace_rules.py`. Il couvre notamment `TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA` et l’usage obligatoire de `solana_pubkey::Pubkey` à la place de `solana_address::Address`.
|
||||
- L’audit mécanique spécifique au projet est exécuté par `python3 scripts/audit_khadhroony_workspace_rules.py`. Il couvre notamment les conventions de composants et `processorName` des matérialisateurs, la pureté de leurs façades, la neutralité des coquilles réservées, `TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA` et l’usage obligatoire de `solana_pubkey::Pubkey` à la place de `solana_address::Address`.
|
||||
|
||||
## Règles de réutilisation des interfaces Solana et SPL
|
||||
|
||||
|
||||
Reference in New Issue
Block a user