v0.1.0-pre.009
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: README.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Khadhroony Bot3
|
||||
|
||||
@@ -56,3 +56,5 @@ cargo clippy --workspace --all-targets
|
||||
`0.1.0-pre.004` porte le décodeur Solana Core dans `kb-lib`. `0.1.0-pre.005` ajoute SPL Memo v1, v3 et v4. `0.1.0-pre.006` ajoute le décodeur SPL Token classique avec ses 28 tags publiés, son wire borné, ses formes d’autorité et son `Batch` structuré. `0.1.0-pre.007` ajoute le programme SPL Associated Token Account avec ses trois instructions, sa forme historique `Create` vide et la validation canonique des PDA pour SPL Token classique et Token‑2022.
|
||||
|
||||
`0.1.0-pre.008` porte le décodeur Token‑2022 maximal, son parseur d’états Mint/Account/Multisig et de TLV, ainsi que le programme indépendant du registre ElGamal. Les deux composants gardent des frontières et des targets de tracing distincts. Tous les décodeurs migrés utilisent les mêmes contrats contextualisés, la même façade publique et aucune dépendance inverse vers `kb-store`.
|
||||
|
||||
`0.1.0-pre.009` porte le décodeur indépendant Metaplex Token Metadata. Il couvre les 58 discriminateurs d’instructions publiés `0..=57`, les 15 variantes de comptes `Key 0..=14`, les PDA officiels et les layouts courants, expérimentaux et historiques. Les metadata externes Metaplex restent séparées des metadata incorporées de Token‑2022, de Metaplex Core et de Bubblegum.
|
||||
|
||||
20
ROADMAP.md
20
ROADMAP.md
@@ -1,5 +1,5 @@
|
||||
<!-- file: ROADMAP.md -->
|
||||
<!-- version: 6 -->
|
||||
<!-- version: 7 -->
|
||||
|
||||
# ROADMAP — khadhroony-bot3
|
||||
|
||||
@@ -96,5 +96,19 @@
|
||||
- [x] Déplacer `ProgramIdEntry` et les fonctions du registre dans `kb-program-ids/src/programs.rs`, avec `lib.rs` limité aux réexports.
|
||||
- [x] Porter les targets de tracing vers `kb-lib.decoder.spl.token_2022` et `kb-lib.decoder.spl.elgamal_registry`.
|
||||
- [x] Conserver les 55 tests Token‑2022/ElGamal et leurs matrices machine-readable.
|
||||
- [ ] Valider `kb-program-ids`, les 251 tests de `kb-lib`, Clippy et le workspace avec Cargo sur la machine de développement.
|
||||
- [ ] Poursuivre avec le décodeur Metaplex Token Metadata après validation.
|
||||
- [x] Valider `kb-program-ids`, les 251 tests de `kb-lib`, Clippy et le workspace avec Cargo sur la machine de développement.
|
||||
- [x] Poursuivre avec le décodeur Metaplex Token Metadata après validation.
|
||||
|
||||
### 0.1.0-pre.009 — Décodeur Metaplex Token Metadata dans `kb-lib`
|
||||
|
||||
- [x] Remplacer le scaffold `kb-lib::decoder::metadata::metaplex_token_metadata` par le décodeur maximal validé de bot2.
|
||||
- [x] Conserver l’inventaire exhaustif des 58 discriminateurs d’instructions `0..=57`, y compris les variantes historiques.
|
||||
- [x] Conserver l’inventaire exhaustif des 15 variantes de comptes `Key 0..=14`, avec rejet explicite de `Uninitialized`.
|
||||
- [x] Porter les parseurs bornés de Metadata, Edition, Master Edition, Edition Marker, Token Record, records d’autorité et de délégation, escrow et Reservation List.
|
||||
- [x] Préserver les validations d’owner, de PDA, de bump, de longueur, de suffixe, de comptes ordonnés et de provenance.
|
||||
- [x] Maintenir les layouts historiques matérialisables avec lifecycle explicite mais définitivement non exécutables.
|
||||
- [x] Ajouter le Program ID Metaplex Token Metadata à `kb-program-ids` sans le classer comme surface native.
|
||||
- [x] Porter le target de tracing vers `kb-lib.decoder.metadata.metaplex_token_metadata`.
|
||||
- [x] Conserver les 69 tests Metaplex et la matrice machine-readable exhaustive.
|
||||
- [ ] Valider `kb-program-ids`, les 320 tests de `kb-lib`, Clippy et le workspace avec Cargo sur la machine de développement.
|
||||
- [ ] Poursuivre avec les matérialisateurs et exécuteurs après validation du port des décodeurs prioritaires.
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"ansi": true,
|
||||
"targets": [
|
||||
"kb_app_demo",
|
||||
"kb_decoder_metadata_metaplex_token_metadata",
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata",
|
||||
"kb-lib.decoder.solana.core",
|
||||
"kb-lib.decoder.spl.associated_token_account",
|
||||
"kb-lib.decoder.spl.elgamal_registry",
|
||||
@@ -1161,42 +1161,42 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_kb_decoder_metadata_metaplex_token_metadata_debug",
|
||||
"name": "file_kb_lib_decoder_metadata_metaplex_token_metadata_debug",
|
||||
"enabled": true,
|
||||
"sink": "file",
|
||||
"level": "debug",
|
||||
"path": "logs/devnet/kb_decoder_metadata_metaplex_token_metadata/debug.log",
|
||||
"path": "logs/devnet/kb-lib/decoder/metadata/metaplex_token_metadata/debug.log",
|
||||
"rotation": "daily",
|
||||
"format": "human",
|
||||
"ansi": false,
|
||||
"targets": [
|
||||
"kb_decoder_metadata_metaplex_token_metadata"
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_kb_decoder_metadata_metaplex_token_metadata_info",
|
||||
"name": "file_kb_lib_decoder_metadata_metaplex_token_metadata_info",
|
||||
"enabled": true,
|
||||
"sink": "file",
|
||||
"level": "info",
|
||||
"path": "logs/devnet/kb_decoder_metadata_metaplex_token_metadata/info.log",
|
||||
"path": "logs/devnet/kb-lib/decoder/metadata/metaplex_token_metadata/info.log",
|
||||
"rotation": "daily",
|
||||
"format": "human",
|
||||
"ansi": false,
|
||||
"targets": [
|
||||
"kb_decoder_metadata_metaplex_token_metadata"
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_kb_decoder_metadata_metaplex_token_metadata_error",
|
||||
"name": "file_kb_lib_decoder_metadata_metaplex_token_metadata_error",
|
||||
"enabled": true,
|
||||
"sink": "file",
|
||||
"level": "error",
|
||||
"path": "logs/devnet/kb_decoder_metadata_metaplex_token_metadata/error.jsonl",
|
||||
"path": "logs/devnet/kb-lib/decoder/metadata/metaplex_token_metadata/error.jsonl",
|
||||
"rotation": "daily",
|
||||
"format": "json",
|
||||
"ansi": false,
|
||||
"targets": [
|
||||
"kb_decoder_metadata_metaplex_token_metadata"
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1624,7 +1624,7 @@
|
||||
"ansi": true,
|
||||
"targets": [
|
||||
"kb_app_demo",
|
||||
"kb_decoder_metadata_metaplex_token_metadata",
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata",
|
||||
"kb-lib.decoder.solana.core",
|
||||
"kb-lib.decoder.spl.associated_token_account",
|
||||
"kb-lib.decoder.spl.elgamal_registry",
|
||||
@@ -2763,42 +2763,42 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_kb_decoder_metadata_metaplex_token_metadata_debug",
|
||||
"name": "file_kb_lib_decoder_metadata_metaplex_token_metadata_debug",
|
||||
"enabled": true,
|
||||
"sink": "file",
|
||||
"level": "debug",
|
||||
"path": "logs/mainnet_research/kb_decoder_metadata_metaplex_token_metadata/debug.log",
|
||||
"path": "logs/mainnet_research/kb-lib/decoder/metadata/metaplex_token_metadata/debug.log",
|
||||
"rotation": "daily",
|
||||
"format": "human",
|
||||
"ansi": false,
|
||||
"targets": [
|
||||
"kb_decoder_metadata_metaplex_token_metadata"
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_kb_decoder_metadata_metaplex_token_metadata_info",
|
||||
"name": "file_kb_lib_decoder_metadata_metaplex_token_metadata_info",
|
||||
"enabled": true,
|
||||
"sink": "file",
|
||||
"level": "info",
|
||||
"path": "logs/mainnet_research/kb_decoder_metadata_metaplex_token_metadata/info.log",
|
||||
"path": "logs/mainnet_research/kb-lib/decoder/metadata/metaplex_token_metadata/info.log",
|
||||
"rotation": "daily",
|
||||
"format": "human",
|
||||
"ansi": false,
|
||||
"targets": [
|
||||
"kb_decoder_metadata_metaplex_token_metadata"
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_kb_decoder_metadata_metaplex_token_metadata_error",
|
||||
"name": "file_kb_lib_decoder_metadata_metaplex_token_metadata_error",
|
||||
"enabled": true,
|
||||
"sink": "file",
|
||||
"level": "error",
|
||||
"path": "logs/mainnet_research/kb_decoder_metadata_metaplex_token_metadata/error.jsonl",
|
||||
"path": "logs/mainnet_research/kb-lib/decoder/metadata/metaplex_token_metadata/error.jsonl",
|
||||
"rotation": "daily",
|
||||
"format": "json",
|
||||
"ansi": false,
|
||||
"targets": [
|
||||
"kb_decoder_metadata_metaplex_token_metadata"
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -3426,7 +3426,7 @@
|
||||
"ansi": true,
|
||||
"targets": [
|
||||
"kb_app_demo",
|
||||
"kb_decoder_metadata_metaplex_token_metadata",
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata",
|
||||
"kb-lib.decoder.solana.core",
|
||||
"kb-lib.decoder.spl.associated_token_account",
|
||||
"kb-lib.decoder.spl.elgamal_registry",
|
||||
@@ -4565,42 +4565,42 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_kb_decoder_metadata_metaplex_token_metadata_debug",
|
||||
"name": "file_kb_lib_decoder_metadata_metaplex_token_metadata_debug",
|
||||
"enabled": true,
|
||||
"sink": "file",
|
||||
"level": "debug",
|
||||
"path": "logs/mainnet/kb_decoder_metadata_metaplex_token_metadata/debug.log",
|
||||
"path": "logs/mainnet/kb-lib/decoder/metadata/metaplex_token_metadata/debug.log",
|
||||
"rotation": "daily",
|
||||
"format": "human",
|
||||
"ansi": false,
|
||||
"targets": [
|
||||
"kb_decoder_metadata_metaplex_token_metadata"
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_kb_decoder_metadata_metaplex_token_metadata_info",
|
||||
"name": "file_kb_lib_decoder_metadata_metaplex_token_metadata_info",
|
||||
"enabled": true,
|
||||
"sink": "file",
|
||||
"level": "info",
|
||||
"path": "logs/mainnet/kb_decoder_metadata_metaplex_token_metadata/info.log",
|
||||
"path": "logs/mainnet/kb-lib/decoder/metadata/metaplex_token_metadata/info.log",
|
||||
"rotation": "daily",
|
||||
"format": "human",
|
||||
"ansi": false,
|
||||
"targets": [
|
||||
"kb_decoder_metadata_metaplex_token_metadata"
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "file_kb_decoder_metadata_metaplex_token_metadata_error",
|
||||
"name": "file_kb_lib_decoder_metadata_metaplex_token_metadata_error",
|
||||
"enabled": true,
|
||||
"sink": "file",
|
||||
"level": "error",
|
||||
"path": "logs/mainnet/kb_decoder_metadata_metaplex_token_metadata/error.jsonl",
|
||||
"path": "logs/mainnet/kb-lib/decoder/metadata/metaplex_token_metadata/error.jsonl",
|
||||
"rotation": "daily",
|
||||
"format": "json",
|
||||
"ansi": false,
|
||||
"targets": [
|
||||
"kb_decoder_metadata_metaplex_token_metadata"
|
||||
"kb-lib.decoder.metadata.metaplex_token_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"schema_version": 2,
|
||||
"milestone": "0.4.7-pre.025",
|
||||
"milestone": "0.1.0-pre.009",
|
||||
"surface_code": "metadata_metaplex_token_metadata",
|
||||
"program_id": "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s",
|
||||
"program_family": "independent_metaplex_foundation_program",
|
||||
"decode_status": "instruction_inventory_exhaustive_0_through_57_and_account_key_inventory_exhaustive_0_through_14",
|
||||
"runtime_registration": "not_enabled_in_pre_008",
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009",
|
||||
"official_sources": [
|
||||
{
|
||||
"kind": "repository",
|
||||
@@ -356,7 +356,7 @@
|
||||
}
|
||||
],
|
||||
"wire": "official_borsh_mpl_token_metadata_5_1_1",
|
||||
"runtime_registration": "pending_full_group_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.003",
|
||||
@@ -392,7 +392,7 @@
|
||||
],
|
||||
"wire": "single_u8_discriminator_official_mpl_token_metadata_5_1_1",
|
||||
"account_contract": "ordered_required_accounts_plus_optional_collection_authority_record_and_bounded_remaining_accounts",
|
||||
"runtime_registration": "pending_broader_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.004",
|
||||
@@ -428,7 +428,7 @@
|
||||
],
|
||||
"wire": "single_u8_discriminator_official_mpl_token_metadata_5_1_1",
|
||||
"account_contract": "ordered_required_accounts_plus_optional_collection_authority_record; collection metadata is writable and collection authority is readonly signer",
|
||||
"runtime_registration": "pending_broader_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.005",
|
||||
@@ -597,7 +597,7 @@
|
||||
"wire": "u8 discriminator + historical DataV2 + bool is_mutable using Borsh 0.10",
|
||||
"account_contract": "metadata, mint, mint_authority signer, payer writable signer, update_authority, system_program, optional rent",
|
||||
"provenance": "historical Metaplex Token Metadata instruction surface; current SDK DataV2 type reused only for exact compatible wire fields",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.010",
|
||||
@@ -624,7 +624,7 @@
|
||||
],
|
||||
"wire": "u8 discriminator + historical Data/Option<Data> fields using Borsh 0.10",
|
||||
"provenance": "historical generated Metaplex Token Metadata surface",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.011",
|
||||
@@ -651,7 +651,7 @@
|
||||
],
|
||||
"wire": "CreateMasterEditionV3: u8 discriminator + Option<u64> max_supply; conversion: u8 discriminator only",
|
||||
"account_contract": "exact generated Rust SDK account order and signer/writable flags; optional rent accepted for CreateMasterEditionV3",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.012",
|
||||
@@ -679,7 +679,7 @@
|
||||
"wire": "u8 discriminator + MintNewEditionFromMasterEditionViaTokenArgs { edition: u64 }",
|
||||
"account_contract": "exact generated Rust SDK account order and signer/writable flags; optional rent accepted after the required program accounts",
|
||||
"edition_marker_contract": "edition marker PDA is writable and corresponds to floor(edition / EDITION_MARKER_BIT_SIZE); PDA derivation validation remains planned with account decoding",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.013",
|
||||
@@ -707,7 +707,7 @@
|
||||
"wire": "u8 discriminator + SetCollectionSizeArgs { size: u64 }",
|
||||
"account_contract": "exact generated Rust SDK account order and signer/writable flags; optional collection authority record accepted",
|
||||
"provenance_boundary": "BubblegumSetCollectionSize is decoded as a Token Metadata bridge instruction and does not claim complete Bubblegum coverage",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.014",
|
||||
@@ -734,7 +734,7 @@
|
||||
],
|
||||
"wire": "u8 discriminator + DelegateArgs or RevokeArgs Borsh enum; DelegateArgs may contain optional AuthorizationData",
|
||||
"account_contract": "14 positional accounts with Metaplex program placeholders for absent optional accounts; exact signer/writable invariants on authority, payer, metadata and optional writable records",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.015",
|
||||
@@ -788,7 +788,7 @@
|
||||
],
|
||||
"wire": "Borsh enums TransferArgs/LockArgs/UnlockArgs/BurnArgs; CloseAccounts discriminator only",
|
||||
"account_contract": "exact generated Rust SDK positional accounts and signer/writable invariants; Metaplex program placeholders accepted for absent optional programmable accounts",
|
||||
"runtime_registration": "pending_full_decoder_and_account_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.016",
|
||||
@@ -816,7 +816,7 @@
|
||||
"wire": "u8 discriminator only",
|
||||
"account_contract": "delegate writable signer, token account writable, edition/mint/token program readonly",
|
||||
"inventory_audit": "official generated Rust SDK instruction module index audited; remaining modules are tracked before account-state decoding",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.017",
|
||||
@@ -852,7 +852,7 @@
|
||||
],
|
||||
"wire": "u8 discriminator only",
|
||||
"account_contract": "exact generated Rust SDK positional signer/writable contracts; BurnNft collection metadata, deprecated printing-token reservation list are optional trailing accounts",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.018",
|
||||
@@ -897,7 +897,7 @@
|
||||
],
|
||||
"wire": "Create/Close/Collect discriminator only; TransferOutOfEscrow discriminator + amount u64",
|
||||
"account_contract": "exact generated Rust SDK signer/writable contracts with optional trailing authority on create and transfer",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.019",
|
||||
@@ -915,7 +915,7 @@
|
||||
],
|
||||
"wire": "u8 discriminator + CreateArgs enum",
|
||||
"account_contract": "nine positional accounts with Metaplex placeholders for optional master edition and SPL Token Program",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.020",
|
||||
@@ -933,7 +933,7 @@
|
||||
],
|
||||
"wire": "u8 discriminator + MintArgs::V1 { amount: u64, authorization_data: Option<AuthorizationData> }",
|
||||
"account_contract": "fifteen positional accounts with Metaplex placeholders for optional token owner, master edition, token record, delegate record and authorization-rule accounts",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.021",
|
||||
@@ -955,7 +955,7 @@
|
||||
],
|
||||
"wire": "u8 discriminator + PrintArgs::{V1,V2} { edition: u64 }",
|
||||
"account_contract": "eighteen positional accounts with a Metaplex placeholder or writable Token Record at position 6",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.022",
|
||||
@@ -984,7 +984,7 @@
|
||||
],
|
||||
"wire": "u8 discriminator + UpdateArgs enum",
|
||||
"account_contract": "eleven positional accounts with Metaplex placeholders for optional delegate record, token, edition and authorization-rule accounts",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.023",
|
||||
@@ -1031,7 +1031,7 @@
|
||||
],
|
||||
"wire": "u8 discriminator + UseArgs or VerificationArgs enum",
|
||||
"account_contract": "twelve positional accounts for Use; eight positional accounts for Verify/Unverify, with Metaplex placeholders for optional accounts",
|
||||
"runtime_registration": "pending_full_decoder_validation"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"pre_release": "0.4.7-pre.024",
|
||||
@@ -1112,7 +1112,7 @@
|
||||
],
|
||||
"wire": "u8 discriminator only",
|
||||
"account_contract": "exact IDL/generated positional signer and writable flags",
|
||||
"runtime_registration": "pending_full_decoder_validation",
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009",
|
||||
"inventory_proof": {
|
||||
"covered_discriminators": [
|
||||
0,
|
||||
@@ -1198,7 +1198,7 @@
|
||||
"uri_bytes": 200,
|
||||
"creators": 5
|
||||
},
|
||||
"runtime_registration": "not_enabled"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"group": "edition_and_master_edition_accounts",
|
||||
@@ -1261,7 +1261,7 @@
|
||||
"bit_order": "most_significant_bit_first"
|
||||
}
|
||||
},
|
||||
"runtime_registration": "not_enabled"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"group": "token_record_account",
|
||||
@@ -1300,7 +1300,7 @@
|
||||
"LockedTransfer",
|
||||
"Migration"
|
||||
],
|
||||
"runtime_registration": "not_enabled"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"group": "delegate_and_authority_records",
|
||||
@@ -1363,7 +1363,7 @@
|
||||
"holder_delegate_role_seeds": [
|
||||
"print_delegate"
|
||||
],
|
||||
"runtime_registration": "not_enabled"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"group": "token_owned_escrow_account",
|
||||
@@ -1405,7 +1405,7 @@
|
||||
"Migrate": "may create or update related programmable records; correlation pending",
|
||||
"Resize": "changes allocated account bytes without changing canonical identity"
|
||||
},
|
||||
"runtime_registration": "not_enabled"
|
||||
"runtime_registration": "enabled_in_kb_lib_pre_009"
|
||||
},
|
||||
{
|
||||
"group": "historical_reservation_lists",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/PROGRAM_REGISTRY_CONTROL.md -->
|
||||
<!-- version: 4 -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Contrôle du registre des programmes
|
||||
|
||||
@@ -250,7 +250,7 @@ Ces identifiants sont détaillés dans `docs/CORE_PROGRAM_IDS.md`. Ils sont couv
|
||||
| `lock_raydium_lp` | `LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE` | `raydium_lock_lp` | `raydium_lock_lp` | `-` | `kb_decoder_lock_raydium_lp` | `reserved_missing` |
|
||||
| `admin_jupiter_lock` | `LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjn` | `jupiter_lock` | `jupiter_lock` | `-` | `kb_decoder_admin_jupiter_lock` | `reserved_missing` |
|
||||
| `admin_pump_fees` | `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ` | `pump_fees` | `pump_fees` | `kb_decoder_pump_fees` | `kb_decoder_admin_pump_fees` | `current_alias` |
|
||||
| `metadata_metaplex_token_metadata` | `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s` | `metaplex_token_metadata` | `metaplex_token_metadata` | `-` | `kb_decoder_metadata_metaplex_token_metadata` | `reserved_missing` |
|
||||
| `metadata_metaplex_token_metadata` | `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s` | `metaplex_token_metadata` | `metaplex_token_metadata` | `-` | `kb_lib::decoder::metadata::metaplex_token_metadata` | `current_migrated` |
|
||||
| `metadata_name_service` | `namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX` | `name_service` | `name_service` | `-` | `kb_decoder_metadata_spl_name_service` | `reserved_missing` |
|
||||
| `nft_metaplex_bubblegum` | `BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY` | `bubblegum` | `bubblegum` | `-` | `kb_decoder_nft_metaplex_bubblegum` | `reserved_missing` |
|
||||
| `nft_metaplex_mpl_core` | `CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d` | `mpl_core` | `mpl_core` | `-` | `kb_decoder_nft_metaplex_mpl_core` | `reserved_missing` |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/SOLANA_INTERFACE_DEPENDENCIES.md -->
|
||||
<!-- version: 30 -->
|
||||
<!-- version: 31 -->
|
||||
|
||||
# Dépendances d’interfaces Solana et SPL
|
||||
|
||||
@@ -281,10 +281,23 @@ Pour chaque nouvelle interface :
|
||||
6. tester les payloads tronqués, inconnus, suffixés et les comptes invalides ;
|
||||
7. documenter toute divergence entre l’interface et le runtime.
|
||||
|
||||
### Metaplex Token Metadata — audit et premier décodage `0.4.7-pre.002`
|
||||
### Metaplex Token Metadata — port maximal `0.1.0-pre.009`
|
||||
|
||||
Le catalogue workspace déclare `mpl-token-metadata ^5.1` avec la seule feature `serde`. La publication officielle résolue reste `5.1.1`; elle fournit les modules générés `accounts`, `instructions`, `types` et `errors` issus de l’IDL Metaplex, sans introduire Anchor. La crate officielle utilise Borsh `< 1.0`; le décodeur référence donc explicitement `borsh 0.10` sous l’alias workspace `borsh_0_10`, distinct de Borsh 1.x utilisé par d’autres interfaces du workspace.
|
||||
|
||||
Le dépôt officiel `metaplex-foundation/mpl-token-metadata` confirme le Program ID `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s`. L’IDL officiel audité porte la version `1.14.0` et le blob `5df4a24f62c2743125be096cc174680790c92c18`; l’inventaire Rust généré des instructions porte le blob `3c42eec629f82e44ba690a7c4bd2177cc78f1d49`.
|
||||
|
||||
`kb_decoder_metadata_metaplex_token_metadata` implémente désormais `InstructionDecoder` pour `CreateMetadataAccountV3` et `UpdateMetadataAccountV2`. Les arguments sont lus avec les types Borsh officiels et projetés avec la feature `serde`; les payloads, chaînes, créateurs, frais, comptes et suffixes sont bornés. L’enregistrement dans le registre runtime reste différé jusqu’à validation de ce premier groupe. Les metadata Token-2022 incorporées, Metaplex Core, Bubblegum et le JSON externe restent des provenances ou composants distincts.
|
||||
`kb_lib::decoder::metadata::metaplex_token_metadata` implémente désormais la couverture exhaustive des
|
||||
58 discriminateurs `0..=57`. Les arguments sont lus avec les types Borsh officiels lorsque le SDK
|
||||
les expose, ou avec un miroir local borné du wire publié pour les variantes historiques. Les
|
||||
payloads, chaînes, créateurs, frais, comptes et suffixes sont bornés.
|
||||
|
||||
Le même composant inventorie les 15 variantes `Key 0..=14` et décode les quatorze layouts
|
||||
représentant un compte réel. Les parseurs utilisent `solana-pubkey ^4.2` pour vérifier owner,
|
||||
PDA et bump, puis les comptes historiques reçoivent une politique de matérialisation historique
|
||||
distincte de leur interdiction d’exécution. `Uninitialized` reste une sentinelle explicitement
|
||||
refusée et toute variante future absente de l’inventaire fait échouer les tests.
|
||||
|
||||
Les metadata Token‑2022 incorporées, Metaplex Core, Bubblegum et le JSON externe restent des
|
||||
provenances ou composants distincts. Aucun fetch HTTP, IPFS ou Arweave n’appartient au replay
|
||||
canonique de cette tranche.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/TRACING_CONTRACT.md -->
|
||||
<!-- version: 17 -->
|
||||
<!-- version: 18 -->
|
||||
|
||||
# Contrat de tracing par crate et composant
|
||||
|
||||
@@ -57,6 +57,7 @@ Les targets déjà migrés vers les noms canoniques bot3 sont :
|
||||
|
||||
```text
|
||||
kb-lib.decoder.solana.core
|
||||
kb-lib.decoder.metadata.metaplex_token_metadata
|
||||
kb-lib.decoder.spl.associated_token_account
|
||||
kb-lib.decoder.spl.elgamal_registry
|
||||
kb-lib.decoder.spl.memo
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# file: kb-lib/Cargo.toml
|
||||
# version: 7
|
||||
# version: 8
|
||||
|
||||
[package]
|
||||
name = "kb-lib"
|
||||
@@ -11,15 +11,18 @@ publish.workspace = true
|
||||
[dependencies]
|
||||
base64.workspace = true
|
||||
borsh.workspace = true
|
||||
borsh_0_10.workspace = true
|
||||
bs58.workspace = true
|
||||
kb-core = { path = "../kb-core" }
|
||||
kb-program-ids = { path = "../kb-program-ids" }
|
||||
mpl-token-metadata.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
sha2.workspace = true
|
||||
solana-address-lookup-table-interface.workspace = true
|
||||
solana-compute-budget-interface.workspace = true
|
||||
solana-loader-v3-interface.workspace = true
|
||||
solana-pubkey.workspace = true
|
||||
solana-sdk-ids.workspace = true
|
||||
solana-stake-interface.workspace = true
|
||||
solana-system-interface.workspace = true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: kb-lib/README.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# kb-lib
|
||||
|
||||
@@ -80,6 +80,24 @@ est `docs/SPL_TOKEN_2022_MATRIX.json`.
|
||||
clé publique ElGamal et le wire complet. La matrice normative est
|
||||
`docs/SPL_ELGAMAL_REGISTRY_MATRIX.json`.
|
||||
|
||||
## Décodeur Metaplex Token Metadata
|
||||
|
||||
`MetadataMetaplexTokenMetadataDecoder` couvre exclusivement
|
||||
`metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s`. Il inventorie exactement les 58
|
||||
discriminateurs `0..=57`, conserve les arguments Borsh, les comptes positionnels,
|
||||
les placeholders optionnels, les chemins outer/CPI et les transactions échouées
|
||||
comme intentions non commitées.
|
||||
|
||||
Le module public
|
||||
`kb_lib::decoder::metadata::metaplex_token_metadata` expose aussi les parseurs
|
||||
bornés des 15 variantes `Key 0..=14` : Metadata, Edition et Master Edition,
|
||||
Edition Marker V1/V2, Token Record, records de délégation et d’autorité, Token
|
||||
Owned Escrow et Reservation List historiques. Chaque parseur vérifie l’owner,
|
||||
le PDA, le bump, la longueur et les suffixes avant projection. Les comptes
|
||||
historiques gardent une provenance et un lifecycle matérialisables, mais une
|
||||
politique d’exécution définitivement interdite. La matrice normative est
|
||||
`docs/METAPLEX_TOKEN_METADATA_MATRIX.json`.
|
||||
|
||||
## API publique utile
|
||||
|
||||
- `SolanaCoreDecoder` : décodeur concret natif ;
|
||||
@@ -89,6 +107,8 @@ clé publique ElGamal et le wire complet. La matrice normative est
|
||||
- `SplToken2022Decoder` : décodeur exact des instructions Token‑2022 ;
|
||||
- `Token2022State`, `Token2022StateKind`, `Token2022TlvEntry` et `parse_token_2022_state()` : API publique de lecture d’état Token‑2022 ;
|
||||
- `SplElgamalRegistryDecoder`, `ElGamalRegistryState` et `parse_elgamal_registry_state()` : API publique du registre ElGamal ;
|
||||
- `MetadataMetaplexTokenMetadataDecoder` : décodeur exact du programme Metaplex Token Metadata ;
|
||||
- `kb_lib::decoder::metadata::metaplex_token_metadata` : parseurs et snapshots publics des comptes Metaplex ;
|
||||
- `InstructionDecoder` : contrat de reconnaissance, couverture et décodage contextualisé ;
|
||||
- `ProtocolDecoder` : contrat de compatibilité avec les observations historiques ;
|
||||
- `CoreInstructionReplayInput` : input source-neutral produit par l’extraction core ;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-lib/src/decoder.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
//! Consolidated decoder modules.
|
||||
|
||||
@@ -138,6 +138,8 @@ pub(crate) use self::spl::spl_token_entry_for_tag;
|
||||
/// Returns the first byte of one retained classic SPL Token payload.
|
||||
pub(crate) use self::spl::spl_token_payload_tag;
|
||||
|
||||
/// Exact decoder for the Metaplex Token Metadata program.
|
||||
pub use self::metadata::MetadataMetaplexTokenMetadataDecoder;
|
||||
/// Exact byte length of one SPL ElGamal registry account.
|
||||
pub use self::spl::ELGAMAL_REGISTRY_ACCOUNT_LEN;
|
||||
/// Parsed SPL ElGamal public-key registry account.
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// file: kb-lib/src/decoder/metadata.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! `metadata` decoder family.
|
||||
|
||||
pub mod metaplex_token_metadata;
|
||||
pub mod spl_name_service;
|
||||
|
||||
/// Exact decoder for the Metaplex Token Metadata program.
|
||||
pub use self::metaplex_token_metadata::MetadataMetaplexTokenMetadataDecoder;
|
||||
|
||||
@@ -1,10 +1,223 @@
|
||||
// file: kb-lib/src/decoder/metadata/metaplex_token_metadata.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Migration boundary for legacy crate `kb_decoder_metadata_metaplex_token_metadata`.
|
||||
//! Contextual instruction and bounded account decoder for Metaplex Token Metadata.
|
||||
|
||||
/// Legacy crate name retained for migration and compatibility tracking.
|
||||
pub const LEGACY_CRATE: &str = "kb_decoder_metadata_metaplex_token_metadata";
|
||||
mod account;
|
||||
mod canonical;
|
||||
mod constants;
|
||||
mod decoder;
|
||||
mod instruction;
|
||||
|
||||
/// Current porting status.
|
||||
pub const MIGRATION_STATUS: &str = "source-preserved-pending-port";
|
||||
/// Approve Collection Authority discriminator.
|
||||
pub(crate) use self::constants::APPROVE_COLLECTION_AUTHORITY_DISCRIMINATOR;
|
||||
/// Approve Use Authority discriminator.
|
||||
pub(crate) use self::constants::APPROVE_USE_AUTHORITY_DISCRIMINATOR;
|
||||
/// Bubblegum Set Collection Size discriminator.
|
||||
pub(crate) use self::constants::BUBBLEGUM_SET_COLLECTION_SIZE_DISCRIMINATOR;
|
||||
/// Burn discriminator.
|
||||
pub(crate) use self::constants::BURN_DISCRIMINATOR;
|
||||
/// Historical Burn Edition NFT discriminator.
|
||||
pub(crate) use self::constants::BURN_EDITION_NFT_DISCRIMINATOR;
|
||||
/// Historical Burn NFT discriminator.
|
||||
pub(crate) use self::constants::BURN_NFT_DISCRIMINATOR;
|
||||
/// Close Accounts discriminator.
|
||||
pub(crate) use self::constants::CLOSE_ACCOUNTS_DISCRIMINATOR;
|
||||
/// Close Escrow Account discriminator.
|
||||
pub(crate) use self::constants::CLOSE_ESCROW_ACCOUNT_DISCRIMINATOR;
|
||||
/// Collect discriminator.
|
||||
pub(crate) use self::constants::COLLECT_DISCRIMINATOR;
|
||||
/// Convert Master Edition V1 to V2 discriminator.
|
||||
pub(crate) use self::constants::CONVERT_MASTER_EDITION_V1_TO_V2_DISCRIMINATOR;
|
||||
/// Modern Create discriminator.
|
||||
pub(crate) use self::constants::CREATE_DISCRIMINATOR;
|
||||
/// Create Escrow Account discriminator.
|
||||
pub(crate) use self::constants::CREATE_ESCROW_ACCOUNT_DISCRIMINATOR;
|
||||
/// Historical Create Master Edition discriminator.
|
||||
pub(crate) use self::constants::CREATE_MASTER_EDITION_DISCRIMINATOR;
|
||||
/// Create Master Edition V3 discriminator.
|
||||
pub(crate) use self::constants::CREATE_MASTER_EDITION_V3_DISCRIMINATOR;
|
||||
/// Historical Create Metadata Account discriminator.
|
||||
pub(crate) use self::constants::CREATE_METADATA_ACCOUNT_DISCRIMINATOR;
|
||||
/// Historical Create Metadata Account V2 discriminator.
|
||||
pub(crate) use self::constants::CREATE_METADATA_ACCOUNT_V2_DISCRIMINATOR;
|
||||
/// Create Metadata Account V3 discriminator.
|
||||
pub(crate) use self::constants::CREATE_METADATA_ACCOUNT_V3_DISCRIMINATOR;
|
||||
/// Delegate discriminator.
|
||||
pub(crate) use self::constants::DELEGATE_DISCRIMINATOR;
|
||||
/// Deprecated Create Master Edition discriminator.
|
||||
pub(crate) use self::constants::DEPRECATED_CREATE_MASTER_EDITION_DISCRIMINATOR;
|
||||
/// Deprecated Create Reservation List discriminator.
|
||||
pub(crate) use self::constants::DEPRECATED_CREATE_RESERVATION_LIST_DISCRIMINATOR;
|
||||
/// Deprecated printing-token mint-new-edition discriminator.
|
||||
pub(crate) use self::constants::DEPRECATED_MINT_NEW_EDITION_VIA_PRINTING_TOKEN_DISCRIMINATOR;
|
||||
/// Deprecated Mint Printing Tokens discriminator.
|
||||
pub(crate) use self::constants::DEPRECATED_MINT_PRINTING_TOKENS_DISCRIMINATOR;
|
||||
/// Deprecated Mint Printing Tokens Via Token discriminator.
|
||||
pub(crate) use self::constants::DEPRECATED_MINT_PRINTING_TOKENS_VIA_TOKEN_DISCRIMINATOR;
|
||||
/// Deprecated Set Reservation List discriminator.
|
||||
pub(crate) use self::constants::DEPRECATED_SET_RESERVATION_LIST_DISCRIMINATOR;
|
||||
/// Number of bytes retained in malformed-wire diagnostics.
|
||||
pub(crate) use self::constants::DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Stable event payload contract version.
|
||||
pub(crate) use self::constants::EVENT_VERSION;
|
||||
/// Freeze Delegated Account discriminator.
|
||||
pub(crate) use self::constants::FREEZE_DELEGATED_ACCOUNT_DISCRIMINATOR;
|
||||
/// Current pre-release instruction inventory.
|
||||
pub(crate) use self::constants::INSTRUCTION_ENTRIES;
|
||||
/// Lock discriminator.
|
||||
pub(crate) use self::constants::LOCK_DISCRIMINATOR;
|
||||
/// Maximum encoded base64 instruction payload size.
|
||||
pub(crate) use self::constants::MAX_BASE64_BYTES;
|
||||
/// Maximum number of instruction accounts accepted by this decoder.
|
||||
pub(crate) use self::constants::MAX_INSTRUCTION_ACCOUNTS;
|
||||
/// Tracing target for this decoder.
|
||||
/// Maximum retained instruction payload size.
|
||||
pub(crate) use self::constants::MAX_INSTRUCTION_BYTES;
|
||||
/// Migrate discriminator.
|
||||
pub(crate) use self::constants::MIGRATE_DISCRIMINATOR;
|
||||
/// Modern Mint discriminator.
|
||||
pub(crate) use self::constants::MINT_DISCRIMINATOR;
|
||||
/// Mint New Edition From Master Edition Via Token discriminator.
|
||||
pub(crate) use self::constants::MINT_NEW_EDITION_FROM_MASTER_EDITION_VIA_TOKEN_DISCRIMINATOR;
|
||||
/// Mint New Edition From Master Edition Via Vault Proxy discriminator.
|
||||
pub(crate) use self::constants::MINT_NEW_EDITION_FROM_MASTER_EDITION_VIA_VAULT_PROXY_DISCRIMINATOR;
|
||||
/// Modern Print discriminator.
|
||||
pub(crate) use self::constants::PRINT_DISCRIMINATOR;
|
||||
/// Puff Metadata discriminator.
|
||||
pub(crate) use self::constants::PUFF_METADATA_DISCRIMINATOR;
|
||||
/// Remove Creator Verification discriminator.
|
||||
pub(crate) use self::constants::REMOVE_CREATOR_VERIFICATION_DISCRIMINATOR;
|
||||
/// Resize discriminator.
|
||||
pub(crate) use self::constants::RESIZE_DISCRIMINATOR;
|
||||
/// Revoke Collection Authority discriminator.
|
||||
pub(crate) use self::constants::REVOKE_COLLECTION_AUTHORITY_DISCRIMINATOR;
|
||||
/// Revoke discriminator.
|
||||
pub(crate) use self::constants::REVOKE_DISCRIMINATOR;
|
||||
/// Revoke Use Authority discriminator.
|
||||
pub(crate) use self::constants::REVOKE_USE_AUTHORITY_DISCRIMINATOR;
|
||||
/// Set And Verify Collection discriminator.
|
||||
pub(crate) use self::constants::SET_AND_VERIFY_COLLECTION_DISCRIMINATOR;
|
||||
/// Set And Verify Sized Collection Item discriminator.
|
||||
pub(crate) use self::constants::SET_AND_VERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR;
|
||||
/// Set Collection Size discriminator.
|
||||
pub(crate) use self::constants::SET_COLLECTION_SIZE_DISCRIMINATOR;
|
||||
/// Set Token Standard discriminator.
|
||||
pub(crate) use self::constants::SET_TOKEN_STANDARD_DISCRIMINATOR;
|
||||
/// Sign Metadata discriminator.
|
||||
pub(crate) use self::constants::SIGN_METADATA_DISCRIMINATOR;
|
||||
/// Stable decoder surface code.
|
||||
pub(crate) use self::constants::SURFACE_CODE;
|
||||
/// Thaw Delegated Account discriminator.
|
||||
pub(crate) use self::constants::THAW_DELEGATED_ACCOUNT_DISCRIMINATOR;
|
||||
/// Canonical tracing target for this crate.
|
||||
pub(crate) use self::constants::TRACING_TARGET;
|
||||
/// Transfer discriminator.
|
||||
pub(crate) use self::constants::TRANSFER_DISCRIMINATOR;
|
||||
/// Transfer Out Of Escrow discriminator.
|
||||
pub(crate) use self::constants::TRANSFER_OUT_OF_ESCROW_DISCRIMINATOR;
|
||||
/// Unlock discriminator.
|
||||
pub(crate) use self::constants::UNLOCK_DISCRIMINATOR;
|
||||
/// Unverify Collection discriminator.
|
||||
pub(crate) use self::constants::UNVERIFY_COLLECTION_DISCRIMINATOR;
|
||||
/// Modern Unverify discriminator.
|
||||
pub(crate) use self::constants::UNVERIFY_DISCRIMINATOR;
|
||||
/// Unverify Sized Collection Item discriminator.
|
||||
pub(crate) use self::constants::UNVERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR;
|
||||
/// Modern Update discriminator.
|
||||
pub(crate) use self::constants::UPDATE_DISCRIMINATOR;
|
||||
/// Historical Update Metadata Account discriminator.
|
||||
pub(crate) use self::constants::UPDATE_METADATA_ACCOUNT_DISCRIMINATOR;
|
||||
/// Update Metadata Account V2 discriminator.
|
||||
pub(crate) use self::constants::UPDATE_METADATA_ACCOUNT_V2_DISCRIMINATOR;
|
||||
/// Update Primary Sale Happened Via Token discriminator.
|
||||
pub(crate) use self::constants::UPDATE_PRIMARY_SALE_HAPPENED_VIA_TOKEN_DISCRIMINATOR;
|
||||
/// Modern Use discriminator.
|
||||
pub(crate) use self::constants::USE_DISCRIMINATOR;
|
||||
/// Utilize discriminator.
|
||||
pub(crate) use self::constants::UTILIZE_DISCRIMINATOR;
|
||||
/// Verify Collection discriminator.
|
||||
pub(crate) use self::constants::VERIFY_COLLECTION_DISCRIMINATOR;
|
||||
/// Modern Verify discriminator.
|
||||
pub(crate) use self::constants::VERIFY_DISCRIMINATOR;
|
||||
/// Verify Sized Collection Item discriminator.
|
||||
pub(crate) use self::constants::VERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR;
|
||||
/// Crate-root access to `ParsedInstruction` from `instruction`.
|
||||
pub(crate) use self::instruction::ParsedInstruction;
|
||||
/// Crate-root access to `decode` from `instruction`.
|
||||
pub(crate) use self::instruction::decode;
|
||||
/// Crate-root access to `entry_for_discriminator` from `instruction`.
|
||||
pub(crate) use self::instruction::entry_for_discriminator;
|
||||
/// Crate-root access to `payload_discriminator` from `instruction`.
|
||||
pub(crate) use self::instruction::payload_discriminator;
|
||||
|
||||
/// Canonical projection shared by Collection and Use Authority records.
|
||||
pub use self::account::AuthorityRecordAccountSnapshot;
|
||||
/// Canonical projection shared by Metadata and Holder delegate records.
|
||||
pub use self::account::DelegateRecordAccountSnapshot;
|
||||
/// Supported edition account layout.
|
||||
pub use self::account::EditionAccountKind;
|
||||
/// Canonical bounded projection of one edition or master-edition account.
|
||||
pub use self::account::EditionAccountSnapshot;
|
||||
/// Supported Edition Marker account layout.
|
||||
pub use self::account::EditionMarkerAccountKind;
|
||||
/// Canonical bounded projection of one Edition Marker account.
|
||||
pub use self::account::EditionMarkerAccountSnapshot;
|
||||
/// Exhaustive published Metaplex account-key inventory.
|
||||
pub use self::account::METADATA_ACCOUNT_LAYOUT_AUDIT;
|
||||
/// Bounded error returned while decoding a Metadata account.
|
||||
pub use self::account::MetadataAccountDecodeError;
|
||||
/// One entry in the exhaustive published account-key audit.
|
||||
pub use self::account::MetadataAccountLayoutAuditEntry;
|
||||
/// Canonical bounded projection of one Metadata account.
|
||||
pub use self::account::MetadataAccountSnapshot;
|
||||
/// One bounded historical reservation entry.
|
||||
pub use self::account::ReservationEntrySnapshot;
|
||||
/// Historical Reservation List account generation.
|
||||
pub use self::account::ReservationListAccountKind;
|
||||
/// Canonical decode-only projection of a historical Reservation List account.
|
||||
pub use self::account::ReservationListAccountSnapshot;
|
||||
/// Canonical projection of one Token Owned Escrow account.
|
||||
pub use self::account::TokenOwnedEscrowAccountSnapshot;
|
||||
/// Authority form used by one Token Owned Escrow account.
|
||||
pub use self::account::TokenOwnedEscrowAuthorityKind;
|
||||
/// Canonical bounded projection of one programmable Token Record account.
|
||||
pub use self::account::TokenRecordAccountSnapshot;
|
||||
/// Decodes one Collection Authority Record account.
|
||||
pub use self::account::decode_collection_authority_record_account;
|
||||
/// Decodes and validates one edition or master-edition account snapshot.
|
||||
pub use self::account::decode_edition_account;
|
||||
/// Decodes and validates one Edition Marker account snapshot.
|
||||
pub use self::account::decode_edition_marker_account;
|
||||
/// Decodes one Holder Delegate Record account.
|
||||
pub use self::account::decode_holder_delegate_record_account;
|
||||
/// Decodes and validates one canonical Metadata account snapshot.
|
||||
pub use self::account::decode_metadata_account;
|
||||
/// Decodes one Metadata Delegate Record account.
|
||||
pub use self::account::decode_metadata_delegate_record_account;
|
||||
/// Decodes one historical Reservation List V1 or V2 account.
|
||||
pub use self::account::decode_reservation_list_account;
|
||||
/// Decodes one Token Owned Escrow account.
|
||||
pub use self::account::decode_token_owned_escrow_account;
|
||||
/// Decodes and validates one programmable Token Record account snapshot.
|
||||
pub use self::account::decode_token_record_account;
|
||||
/// Decodes one Use Authority Record account.
|
||||
pub use self::account::decode_use_authority_record_account;
|
||||
/// Stable identity and policy of one canonical account snapshot.
|
||||
pub use self::canonical::CanonicalAccountIdentity;
|
||||
/// Lifecycle class of one canonical account layout.
|
||||
pub use self::canonical::CanonicalAccountLifecycle;
|
||||
/// Provenance retained for one canonical account observation.
|
||||
pub use self::canonical::CanonicalAccountProvenance;
|
||||
/// Execution policy separated from historical materialization.
|
||||
pub use self::canonical::CanonicalExecutionPolicy;
|
||||
/// Materialization policy for active or historical state.
|
||||
pub use self::canonical::CanonicalMaterializationPolicy;
|
||||
/// Canonical account envelope used by materializers and replay.
|
||||
pub use self::canonical::CanonicalMetadataAccountSnapshot;
|
||||
/// Typed canonical Metaplex account state.
|
||||
pub use self::canonical::CanonicalMetadataAccountState;
|
||||
/// Origin of one canonical account observation.
|
||||
pub use self::canonical::CanonicalObservationSource;
|
||||
/// Exact Metaplex Token Metadata decoder.
|
||||
pub use self::decoder::MetadataMetaplexTokenMetadataDecoder;
|
||||
|
||||
2631
kb-lib/src/decoder/metadata/metaplex_token_metadata/account.rs
Normal file
2631
kb-lib/src/decoder/metadata/metaplex_token_metadata/account.rs
Normal file
File diff suppressed because it is too large
Load Diff
425
kb-lib/src/decoder/metadata/metaplex_token_metadata/canonical.rs
Normal file
425
kb-lib/src/decoder/metadata/metaplex_token_metadata/canonical.rs
Normal file
@@ -0,0 +1,425 @@
|
||||
// file: kb-lib/src/decoder/metadata/metaplex_token_metadata/canonical.rs
|
||||
// version: 2
|
||||
|
||||
//! Canonical Metaplex account identities, provenance and materialization policy.
|
||||
|
||||
/// Lifecycle class of one decoded Metaplex account layout.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CanonicalAccountLifecycle {
|
||||
/// Current account layout used by supported runtime flows.
|
||||
Active,
|
||||
/// Published account layout whose runtime surface is still experimental.
|
||||
ActiveExperimental,
|
||||
/// Historical account layout retained for ledger replay and backfill.
|
||||
Historical,
|
||||
}
|
||||
|
||||
/// Materialization policy attached to one canonical account snapshot.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CanonicalMaterializationPolicy {
|
||||
/// Materialize the latest committed state of an active account.
|
||||
ActiveState,
|
||||
/// Materialize historical state with explicit lifecycle provenance.
|
||||
HistoricalState,
|
||||
}
|
||||
|
||||
/// Execution policy attached to one canonical account layout.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CanonicalExecutionPolicy {
|
||||
/// The layout belongs to current operations that may later be executable.
|
||||
CurrentCandidate,
|
||||
/// The layout belongs to an experimental operation requiring explicit activation.
|
||||
ExperimentalCandidate,
|
||||
/// Historical state must never be exposed by an executor.
|
||||
NeverHistorical,
|
||||
}
|
||||
|
||||
/// Origin of one canonical account observation.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CanonicalObservationSource {
|
||||
/// Account observed from a live subscription or direct live read.
|
||||
Live,
|
||||
/// Account reconstructed while replaying already stored transactions.
|
||||
Replay,
|
||||
/// Account discovered while backfilling historical ledger data.
|
||||
Backfill,
|
||||
/// Account read to repair a detected ingestion gap.
|
||||
Repair,
|
||||
/// Synthetic account used only by bounded validation tests.
|
||||
Synthetic,
|
||||
}
|
||||
|
||||
/// Provenance retained for one canonical account observation.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct CanonicalAccountProvenance {
|
||||
/// Observation source.
|
||||
pub source: CanonicalObservationSource,
|
||||
/// Slot associated with the account state when known.
|
||||
pub slot: std::option::Option<u64>,
|
||||
/// Provider write version when available.
|
||||
pub write_version: std::option::Option<u64>,
|
||||
/// Transaction signature responsible for the state when known.
|
||||
pub signature: std::option::Option<String>,
|
||||
/// Instruction index associated with the mutation when known.
|
||||
pub instruction_index: std::option::Option<u32>,
|
||||
/// Inner-instruction index associated with the mutation when known.
|
||||
pub inner_instruction_index: std::option::Option<u32>,
|
||||
/// Whether the source state is committed according to the caller's boundary.
|
||||
pub committed: bool,
|
||||
}
|
||||
|
||||
/// Stable identity and policy of one canonical Metaplex account snapshot.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct CanonicalAccountIdentity {
|
||||
/// Stable identity formed from program id and canonical account address.
|
||||
pub stable_id: String,
|
||||
/// Canonical Metaplex Token Metadata program id.
|
||||
pub program_id: String,
|
||||
/// Canonical account address.
|
||||
pub account: String,
|
||||
/// Published layout name.
|
||||
pub layout: String,
|
||||
/// Exact published `Key` discriminant.
|
||||
pub discriminant: u8,
|
||||
/// Internal canonical-model version.
|
||||
pub canonical_version: u16,
|
||||
/// Published lifecycle class.
|
||||
pub lifecycle: CanonicalAccountLifecycle,
|
||||
/// Materialization policy, including historical backfill state.
|
||||
pub materialization: CanonicalMaterializationPolicy,
|
||||
/// Execution policy separated from materialization.
|
||||
pub execution: CanonicalExecutionPolicy,
|
||||
}
|
||||
|
||||
/// Typed state carried by one canonical Metaplex account snapshot.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum CanonicalMetadataAccountState {
|
||||
/// Metadata account state.
|
||||
Metadata(crate::decoder::metadata::metaplex_token_metadata::MetadataAccountSnapshot),
|
||||
/// Master Edition or printed Edition state.
|
||||
Edition(crate::decoder::metadata::metaplex_token_metadata::EditionAccountSnapshot),
|
||||
/// Edition Marker state.
|
||||
EditionMarker(crate::decoder::metadata::metaplex_token_metadata::EditionMarkerAccountSnapshot),
|
||||
/// Programmable Token Record state.
|
||||
TokenRecord(crate::decoder::metadata::metaplex_token_metadata::TokenRecordAccountSnapshot),
|
||||
/// Metadata or holder delegate state.
|
||||
DelegateRecord(
|
||||
crate::decoder::metadata::metaplex_token_metadata::DelegateRecordAccountSnapshot,
|
||||
),
|
||||
/// Collection or use authority state.
|
||||
AuthorityRecord(
|
||||
crate::decoder::metadata::metaplex_token_metadata::AuthorityRecordAccountSnapshot,
|
||||
),
|
||||
/// Token-owned escrow state.
|
||||
TokenOwnedEscrow(
|
||||
crate::decoder::metadata::metaplex_token_metadata::TokenOwnedEscrowAccountSnapshot,
|
||||
),
|
||||
/// Historical Reservation List state.
|
||||
ReservationList(
|
||||
crate::decoder::metadata::metaplex_token_metadata::ReservationListAccountSnapshot,
|
||||
),
|
||||
}
|
||||
|
||||
/// Canonical envelope used by future materializers and stateful replay.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CanonicalMetadataAccountSnapshot {
|
||||
/// Stable identity and lifecycle policy.
|
||||
pub identity: CanonicalAccountIdentity,
|
||||
/// Observation provenance.
|
||||
pub provenance: CanonicalAccountProvenance,
|
||||
/// Typed bounded state.
|
||||
pub state: CanonicalMetadataAccountState,
|
||||
}
|
||||
|
||||
fn canonical_identity(
|
||||
account: &str,
|
||||
layout: &str,
|
||||
discriminant: u8,
|
||||
lifecycle: CanonicalAccountLifecycle,
|
||||
) -> CanonicalAccountIdentity {
|
||||
let program_id = kb_program_ids::METADATA_METAPLEX_TOKEN_METADATA_PROGRAM_ID.to_string();
|
||||
let materialization = match lifecycle {
|
||||
CanonicalAccountLifecycle::Historical => CanonicalMaterializationPolicy::HistoricalState,
|
||||
CanonicalAccountLifecycle::Active | CanonicalAccountLifecycle::ActiveExperimental => {
|
||||
CanonicalMaterializationPolicy::ActiveState
|
||||
},
|
||||
};
|
||||
let execution = match lifecycle {
|
||||
CanonicalAccountLifecycle::Historical => CanonicalExecutionPolicy::NeverHistorical,
|
||||
CanonicalAccountLifecycle::Active => CanonicalExecutionPolicy::CurrentCandidate,
|
||||
CanonicalAccountLifecycle::ActiveExperimental => {
|
||||
CanonicalExecutionPolicy::ExperimentalCandidate
|
||||
},
|
||||
};
|
||||
return CanonicalAccountIdentity {
|
||||
stable_id: format!("{program_id}:{account}"),
|
||||
program_id,
|
||||
account: account.to_string(),
|
||||
layout: layout.to_string(),
|
||||
discriminant,
|
||||
canonical_version: 1,
|
||||
lifecycle,
|
||||
materialization,
|
||||
execution,
|
||||
};
|
||||
}
|
||||
|
||||
impl CanonicalMetadataAccountSnapshot {
|
||||
/// Wraps one Metadata account snapshot with stable identity and provenance.
|
||||
pub fn from_metadata(
|
||||
snapshot: crate::decoder::metadata::metaplex_token_metadata::MetadataAccountSnapshot,
|
||||
provenance: CanonicalAccountProvenance,
|
||||
) -> Self {
|
||||
let identity = canonical_identity(
|
||||
&snapshot.account,
|
||||
"MetadataV1",
|
||||
mpl_token_metadata::types::Key::MetadataV1 as u8,
|
||||
CanonicalAccountLifecycle::Active,
|
||||
);
|
||||
return Self {
|
||||
identity,
|
||||
provenance,
|
||||
state: CanonicalMetadataAccountState::Metadata(snapshot),
|
||||
};
|
||||
}
|
||||
|
||||
/// Wraps one Edition or Master Edition snapshot with exact lifecycle policy.
|
||||
pub fn from_edition(
|
||||
snapshot: crate::decoder::metadata::metaplex_token_metadata::EditionAccountSnapshot,
|
||||
provenance: CanonicalAccountProvenance,
|
||||
) -> Self {
|
||||
let (layout, discriminant, lifecycle) = match snapshot.kind {
|
||||
crate::decoder::metadata::metaplex_token_metadata::EditionAccountKind::MasterEditionV1 => (
|
||||
"MasterEditionV1",
|
||||
mpl_token_metadata::types::Key::MasterEditionV1 as u8,
|
||||
CanonicalAccountLifecycle::Historical,
|
||||
),
|
||||
crate::decoder::metadata::metaplex_token_metadata::EditionAccountKind::MasterEditionV2 => (
|
||||
"MasterEditionV2",
|
||||
mpl_token_metadata::types::Key::MasterEditionV2 as u8,
|
||||
CanonicalAccountLifecycle::Active,
|
||||
),
|
||||
crate::decoder::metadata::metaplex_token_metadata::EditionAccountKind::EditionV1 => (
|
||||
"EditionV1",
|
||||
mpl_token_metadata::types::Key::EditionV1 as u8,
|
||||
CanonicalAccountLifecycle::Active,
|
||||
),
|
||||
};
|
||||
let identity = canonical_identity(&snapshot.account, layout, discriminant, lifecycle);
|
||||
return Self {
|
||||
identity,
|
||||
provenance,
|
||||
state: CanonicalMetadataAccountState::Edition(snapshot),
|
||||
};
|
||||
}
|
||||
|
||||
/// Wraps one Edition Marker snapshot with exact lifecycle policy.
|
||||
pub fn from_edition_marker(
|
||||
snapshot: crate::decoder::metadata::metaplex_token_metadata::EditionMarkerAccountSnapshot,
|
||||
provenance: CanonicalAccountProvenance,
|
||||
) -> Self {
|
||||
let (layout, discriminant, lifecycle) = match snapshot.kind {
|
||||
crate::decoder::metadata::metaplex_token_metadata::EditionMarkerAccountKind::EditionMarkerV1 => (
|
||||
"EditionMarker",
|
||||
mpl_token_metadata::types::Key::EditionMarker as u8,
|
||||
CanonicalAccountLifecycle::Active,
|
||||
),
|
||||
crate::decoder::metadata::metaplex_token_metadata::EditionMarkerAccountKind::EditionMarkerV2 => (
|
||||
"EditionMarkerV2",
|
||||
mpl_token_metadata::types::Key::EditionMarkerV2 as u8,
|
||||
CanonicalAccountLifecycle::ActiveExperimental,
|
||||
),
|
||||
};
|
||||
let identity = canonical_identity(&snapshot.account, layout, discriminant, lifecycle);
|
||||
return Self {
|
||||
identity,
|
||||
provenance,
|
||||
state: CanonicalMetadataAccountState::EditionMarker(snapshot),
|
||||
};
|
||||
}
|
||||
|
||||
/// Wraps one Token Record snapshot.
|
||||
pub fn from_token_record(
|
||||
snapshot: crate::decoder::metadata::metaplex_token_metadata::TokenRecordAccountSnapshot,
|
||||
provenance: CanonicalAccountProvenance,
|
||||
) -> Self {
|
||||
let identity = canonical_identity(
|
||||
&snapshot.account,
|
||||
"TokenRecord",
|
||||
mpl_token_metadata::types::Key::TokenRecord as u8,
|
||||
CanonicalAccountLifecycle::Active,
|
||||
);
|
||||
return Self {
|
||||
identity,
|
||||
provenance,
|
||||
state: CanonicalMetadataAccountState::TokenRecord(snapshot),
|
||||
};
|
||||
}
|
||||
|
||||
/// Wraps one Metadata or Holder Delegate snapshot.
|
||||
pub fn from_delegate_record(
|
||||
snapshot: crate::decoder::metadata::metaplex_token_metadata::DelegateRecordAccountSnapshot,
|
||||
provenance: CanonicalAccountProvenance,
|
||||
) -> Self {
|
||||
let (layout, discriminant) = if snapshot.kind == "MetadataDelegateRecord" {
|
||||
("MetadataDelegate", mpl_token_metadata::types::Key::MetadataDelegate as u8)
|
||||
} else {
|
||||
("HolderDelegate", mpl_token_metadata::types::Key::HolderDelegate as u8)
|
||||
};
|
||||
let identity = canonical_identity(
|
||||
&snapshot.account,
|
||||
layout,
|
||||
discriminant,
|
||||
CanonicalAccountLifecycle::Active,
|
||||
);
|
||||
return Self {
|
||||
identity,
|
||||
provenance,
|
||||
state: CanonicalMetadataAccountState::DelegateRecord(snapshot),
|
||||
};
|
||||
}
|
||||
|
||||
/// Wraps one Collection or Use Authority snapshot.
|
||||
pub fn from_authority_record(
|
||||
snapshot: crate::decoder::metadata::metaplex_token_metadata::AuthorityRecordAccountSnapshot,
|
||||
provenance: CanonicalAccountProvenance,
|
||||
) -> Self {
|
||||
let (layout, discriminant) = if snapshot.kind == "CollectionAuthorityRecord" {
|
||||
(
|
||||
"CollectionAuthorityRecord",
|
||||
mpl_token_metadata::types::Key::CollectionAuthorityRecord as u8,
|
||||
)
|
||||
} else {
|
||||
("UseAuthorityRecord", mpl_token_metadata::types::Key::UseAuthorityRecord as u8)
|
||||
};
|
||||
let identity = canonical_identity(
|
||||
&snapshot.account,
|
||||
layout,
|
||||
discriminant,
|
||||
CanonicalAccountLifecycle::Active,
|
||||
);
|
||||
return Self {
|
||||
identity,
|
||||
provenance,
|
||||
state: CanonicalMetadataAccountState::AuthorityRecord(snapshot),
|
||||
};
|
||||
}
|
||||
|
||||
/// Wraps one Token Owned Escrow snapshot.
|
||||
pub fn from_token_owned_escrow(
|
||||
snapshot: crate::decoder::metadata::metaplex_token_metadata::TokenOwnedEscrowAccountSnapshot,
|
||||
provenance: CanonicalAccountProvenance,
|
||||
) -> Self {
|
||||
let identity = canonical_identity(
|
||||
&snapshot.account,
|
||||
"TokenOwnedEscrow",
|
||||
mpl_token_metadata::types::Key::TokenOwnedEscrow as u8,
|
||||
CanonicalAccountLifecycle::Active,
|
||||
);
|
||||
return Self {
|
||||
identity,
|
||||
provenance,
|
||||
state: CanonicalMetadataAccountState::TokenOwnedEscrow(snapshot),
|
||||
};
|
||||
}
|
||||
|
||||
/// Wraps one historical Reservation List snapshot as materializable historical state.
|
||||
pub fn from_reservation_list(
|
||||
snapshot: crate::decoder::metadata::metaplex_token_metadata::ReservationListAccountSnapshot,
|
||||
provenance: CanonicalAccountProvenance,
|
||||
) -> Self {
|
||||
let (layout, discriminant) = match snapshot.kind {
|
||||
crate::decoder::metadata::metaplex_token_metadata::ReservationListAccountKind::V1 => {
|
||||
("ReservationListV1", mpl_token_metadata::types::Key::ReservationListV1 as u8)
|
||||
},
|
||||
crate::decoder::metadata::metaplex_token_metadata::ReservationListAccountKind::V2 => {
|
||||
("ReservationListV2", mpl_token_metadata::types::Key::ReservationListV2 as u8)
|
||||
},
|
||||
};
|
||||
let identity = canonical_identity(
|
||||
&snapshot.account,
|
||||
layout,
|
||||
discriminant,
|
||||
CanonicalAccountLifecycle::Historical,
|
||||
);
|
||||
return Self {
|
||||
identity,
|
||||
provenance,
|
||||
state: CanonicalMetadataAccountState::ReservationList(snapshot),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn historical_state_is_materializable_but_never_executable() {
|
||||
let snapshot = crate::decoder::metadata::metaplex_token_metadata::ReservationListAccountSnapshot {
|
||||
account: "reservation-account".to_string(),
|
||||
bump: 1,
|
||||
kind: crate::decoder::metadata::metaplex_token_metadata::ReservationListAccountKind::V1,
|
||||
master_edition: "master-edition".to_string(),
|
||||
resource: "resource".to_string(),
|
||||
supply_snapshot: std::option::Option::Some(7),
|
||||
reservations: std::vec::Vec::new(),
|
||||
total_reservation_spots: 0,
|
||||
current_reservation_spots: 0,
|
||||
payload_json: serde_json::json!({}),
|
||||
};
|
||||
let provenance = super::CanonicalAccountProvenance {
|
||||
source: super::CanonicalObservationSource::Backfill,
|
||||
slot: std::option::Option::Some(42),
|
||||
write_version: std::option::Option::None,
|
||||
signature: std::option::Option::Some("historical-signature".to_string()),
|
||||
instruction_index: std::option::Option::Some(3),
|
||||
inner_instruction_index: std::option::Option::None,
|
||||
committed: true,
|
||||
};
|
||||
let canonical =
|
||||
super::CanonicalMetadataAccountSnapshot::from_reservation_list(snapshot, provenance);
|
||||
assert_eq!(canonical.identity.lifecycle, super::CanonicalAccountLifecycle::Historical);
|
||||
assert_eq!(
|
||||
canonical.identity.materialization,
|
||||
super::CanonicalMaterializationPolicy::HistoricalState
|
||||
);
|
||||
assert_eq!(canonical.identity.execution, super::CanonicalExecutionPolicy::NeverHistorical);
|
||||
assert_eq!(canonical.provenance.source, super::CanonicalObservationSource::Backfill);
|
||||
assert!(canonical.identity.stable_id.ends_with(":reservation-account"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn active_and_experimental_layouts_keep_distinct_policies() {
|
||||
let metadata = crate::decoder::metadata::metaplex_token_metadata::MetadataAccountSnapshot {
|
||||
account: "metadata-account".to_string(),
|
||||
bump: 1,
|
||||
mint: "mint".to_string(),
|
||||
update_authority: "authority".to_string(),
|
||||
name: "name".to_string(),
|
||||
symbol: "symbol".to_string(),
|
||||
uri: "uri".to_string(),
|
||||
seller_fee_basis_points: 0,
|
||||
primary_sale_happened: false,
|
||||
is_mutable: true,
|
||||
payload_json: serde_json::json!({}),
|
||||
};
|
||||
let provenance = super::CanonicalAccountProvenance {
|
||||
source: super::CanonicalObservationSource::Live,
|
||||
slot: std::option::Option::Some(1),
|
||||
write_version: std::option::Option::Some(2),
|
||||
signature: std::option::Option::None,
|
||||
instruction_index: std::option::Option::None,
|
||||
inner_instruction_index: std::option::Option::None,
|
||||
committed: true,
|
||||
};
|
||||
let canonical =
|
||||
super::CanonicalMetadataAccountSnapshot::from_metadata(metadata, provenance);
|
||||
assert_eq!(canonical.identity.lifecycle, super::CanonicalAccountLifecycle::Active);
|
||||
assert_eq!(
|
||||
canonical.identity.materialization,
|
||||
super::CanonicalMaterializationPolicy::ActiveState
|
||||
);
|
||||
assert_eq!(canonical.identity.execution, super::CanonicalExecutionPolicy::CurrentCandidate);
|
||||
assert_eq!(canonical.identity.discriminant, 4);
|
||||
assert_eq!(canonical.identity.canonical_version, 1);
|
||||
}
|
||||
}
|
||||
257
kb-lib/src/decoder/metadata/metaplex_token_metadata/constants.rs
Normal file
257
kb-lib/src/decoder/metadata/metaplex_token_metadata/constants.rs
Normal file
@@ -0,0 +1,257 @@
|
||||
// file: kb-lib/src/decoder/metadata/metaplex_token_metadata/constants.rs
|
||||
// version: 29
|
||||
|
||||
//! Internal constants for Metaplex Token Metadata decoding.
|
||||
|
||||
/// Stable decoder surface code.
|
||||
pub(crate) const SURFACE_CODE: &str = "metadata_metaplex_token_metadata";
|
||||
/// Maximum retained instruction payload size.
|
||||
pub(crate) const MAX_INSTRUCTION_BYTES: usize = 16_384;
|
||||
/// Maximum encoded base64 instruction payload size.
|
||||
pub(crate) const MAX_BASE64_BYTES: usize = 21_852;
|
||||
/// Maximum number of instruction accounts accepted by this decoder.
|
||||
pub(crate) const MAX_INSTRUCTION_ACCOUNTS: usize = 64;
|
||||
/// Number of bytes retained in malformed-wire diagnostics.
|
||||
pub(crate) const DIAGNOSTIC_PREFIX_BYTES: usize = 32;
|
||||
/// Stable event payload contract version.
|
||||
pub(crate) const EVENT_VERSION: u32 = 1;
|
||||
/// Deprecated Create Master Edition discriminator.
|
||||
pub(crate) const DEPRECATED_CREATE_MASTER_EDITION_DISCRIMINATOR: u8 = 2;
|
||||
/// Deprecated Set Reservation List discriminator.
|
||||
pub(crate) const DEPRECATED_SET_RESERVATION_LIST_DISCRIMINATOR: u8 = 5;
|
||||
/// Deprecated Create Reservation List discriminator.
|
||||
pub(crate) const DEPRECATED_CREATE_RESERVATION_LIST_DISCRIMINATOR: u8 = 6;
|
||||
/// Deprecated Mint Printing Tokens Via Token discriminator.
|
||||
pub(crate) const DEPRECATED_MINT_PRINTING_TOKENS_VIA_TOKEN_DISCRIMINATOR: u8 = 8;
|
||||
/// Deprecated Mint Printing Tokens discriminator.
|
||||
pub(crate) const DEPRECATED_MINT_PRINTING_TOKENS_DISCRIMINATOR: u8 = 9;
|
||||
/// Historical Create Master Edition discriminator.
|
||||
pub(crate) const CREATE_MASTER_EDITION_DISCRIMINATOR: u8 = 10;
|
||||
/// Deprecated printing-token mint-new-edition discriminator.
|
||||
pub(crate) const DEPRECATED_MINT_NEW_EDITION_VIA_PRINTING_TOKEN_DISCRIMINATOR: u8 = 3;
|
||||
/// Historical Create Metadata Account discriminator.
|
||||
pub(crate) const CREATE_METADATA_ACCOUNT_DISCRIMINATOR: u8 = 0;
|
||||
/// Historical Update Metadata Account discriminator.
|
||||
pub(crate) const UPDATE_METADATA_ACCOUNT_DISCRIMINATOR: u8 = 1;
|
||||
/// Historical Create Metadata Account V2 discriminator.
|
||||
pub(crate) const CREATE_METADATA_ACCOUNT_V2_DISCRIMINATOR: u8 = 16;
|
||||
/// Create Metadata Account V3 discriminator.
|
||||
pub(crate) const CREATE_METADATA_ACCOUNT_V3_DISCRIMINATOR: u8 = 33;
|
||||
/// Update Metadata Account V2 discriminator.
|
||||
pub(crate) const UPDATE_METADATA_ACCOUNT_V2_DISCRIMINATOR: u8 = 15;
|
||||
/// Verify Collection discriminator.
|
||||
pub(crate) const VERIFY_COLLECTION_DISCRIMINATOR: u8 = 18;
|
||||
/// Unverify Collection discriminator.
|
||||
pub(crate) const UNVERIFY_COLLECTION_DISCRIMINATOR: u8 = 22;
|
||||
/// Set And Verify Collection discriminator.
|
||||
pub(crate) const SET_AND_VERIFY_COLLECTION_DISCRIMINATOR: u8 = 25;
|
||||
/// Approve Collection Authority discriminator.
|
||||
pub(crate) const APPROVE_COLLECTION_AUTHORITY_DISCRIMINATOR: u8 = 23;
|
||||
/// Revoke Collection Authority discriminator.
|
||||
pub(crate) const REVOKE_COLLECTION_AUTHORITY_DISCRIMINATOR: u8 = 24;
|
||||
/// Verify Sized Collection Item discriminator.
|
||||
pub(crate) const VERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR: u8 = 30;
|
||||
/// Unverify Sized Collection Item discriminator.
|
||||
pub(crate) const UNVERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR: u8 = 31;
|
||||
/// Set And Verify Sized Collection Item discriminator.
|
||||
pub(crate) const SET_AND_VERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR: u8 = 32;
|
||||
/// Sign Metadata discriminator.
|
||||
pub(crate) const SIGN_METADATA_DISCRIMINATOR: u8 = 7;
|
||||
/// Update Primary Sale Happened Via Token discriminator.
|
||||
pub(crate) const UPDATE_PRIMARY_SALE_HAPPENED_VIA_TOKEN_DISCRIMINATOR: u8 = 4;
|
||||
/// Utilize discriminator.
|
||||
pub(crate) const UTILIZE_DISCRIMINATOR: u8 = 19;
|
||||
/// Approve Use Authority discriminator.
|
||||
pub(crate) const APPROVE_USE_AUTHORITY_DISCRIMINATOR: u8 = 20;
|
||||
/// Revoke Use Authority discriminator.
|
||||
pub(crate) const REVOKE_USE_AUTHORITY_DISCRIMINATOR: u8 = 21;
|
||||
/// Puff Metadata discriminator.
|
||||
pub(crate) const PUFF_METADATA_DISCRIMINATOR: u8 = 14;
|
||||
/// Freeze Delegated Account discriminator.
|
||||
pub(crate) const FREEZE_DELEGATED_ACCOUNT_DISCRIMINATOR: u8 = 26;
|
||||
/// Thaw Delegated Account discriminator.
|
||||
pub(crate) const THAW_DELEGATED_ACCOUNT_DISCRIMINATOR: u8 = 27;
|
||||
/// Remove Creator Verification discriminator.
|
||||
pub(crate) const REMOVE_CREATOR_VERIFICATION_DISCRIMINATOR: u8 = 28;
|
||||
/// Set Token Standard discriminator.
|
||||
pub(crate) const SET_TOKEN_STANDARD_DISCRIMINATOR: u8 = 35;
|
||||
/// Mint New Edition From Master Edition Via Token discriminator.
|
||||
pub(crate) const MINT_NEW_EDITION_FROM_MASTER_EDITION_VIA_TOKEN_DISCRIMINATOR: u8 = 11;
|
||||
/// Mint New Edition From Master Edition Via Vault Proxy discriminator.
|
||||
pub(crate) const MINT_NEW_EDITION_FROM_MASTER_EDITION_VIA_VAULT_PROXY_DISCRIMINATOR: u8 = 13;
|
||||
/// Convert Master Edition V1 to V2 discriminator.
|
||||
pub(crate) const CONVERT_MASTER_EDITION_V1_TO_V2_DISCRIMINATOR: u8 = 12;
|
||||
/// Create Master Edition V3 discriminator.
|
||||
pub(crate) const CREATE_MASTER_EDITION_V3_DISCRIMINATOR: u8 = 17;
|
||||
/// Set Collection Size discriminator.
|
||||
pub(crate) const SET_COLLECTION_SIZE_DISCRIMINATOR: u8 = 34;
|
||||
/// Bubblegum Set Collection Size discriminator.
|
||||
pub(crate) const BUBBLEGUM_SET_COLLECTION_SIZE_DISCRIMINATOR: u8 = 36;
|
||||
/// Create Escrow Account discriminator.
|
||||
pub(crate) const CREATE_ESCROW_ACCOUNT_DISCRIMINATOR: u8 = 38;
|
||||
/// Close Escrow Account discriminator.
|
||||
pub(crate) const CLOSE_ESCROW_ACCOUNT_DISCRIMINATOR: u8 = 39;
|
||||
/// Transfer Out Of Escrow discriminator.
|
||||
pub(crate) const TRANSFER_OUT_OF_ESCROW_DISCRIMINATOR: u8 = 40;
|
||||
/// Collect discriminator.
|
||||
pub(crate) const COLLECT_DISCRIMINATOR: u8 = 54;
|
||||
/// Historical Burn NFT discriminator.
|
||||
pub(crate) const BURN_NFT_DISCRIMINATOR: u8 = 29;
|
||||
/// Historical Burn Edition NFT discriminator.
|
||||
pub(crate) const BURN_EDITION_NFT_DISCRIMINATOR: u8 = 37;
|
||||
/// Burn discriminator.
|
||||
pub(crate) const BURN_DISCRIMINATOR: u8 = 41;
|
||||
/// Lock discriminator.
|
||||
pub(crate) const LOCK_DISCRIMINATOR: u8 = 46;
|
||||
/// Unlock discriminator.
|
||||
pub(crate) const UNLOCK_DISCRIMINATOR: u8 = 47;
|
||||
/// Transfer discriminator.
|
||||
pub(crate) const TRANSFER_DISCRIMINATOR: u8 = 49;
|
||||
/// Close Accounts discriminator.
|
||||
pub(crate) const CLOSE_ACCOUNTS_DISCRIMINATOR: u8 = 57;
|
||||
/// Modern Create discriminator.
|
||||
pub(crate) const CREATE_DISCRIMINATOR: u8 = 42;
|
||||
/// Modern Mint discriminator.
|
||||
pub(crate) const MINT_DISCRIMINATOR: u8 = 43;
|
||||
/// Modern Print discriminator.
|
||||
pub(crate) const PRINT_DISCRIMINATOR: u8 = 55;
|
||||
/// Modern Update discriminator.
|
||||
pub(crate) const UPDATE_DISCRIMINATOR: u8 = 50;
|
||||
/// Modern Use discriminator.
|
||||
pub(crate) const USE_DISCRIMINATOR: u8 = 51;
|
||||
/// Modern Verify discriminator.
|
||||
pub(crate) const VERIFY_DISCRIMINATOR: u8 = 52;
|
||||
/// Modern Unverify discriminator.
|
||||
pub(crate) const UNVERIFY_DISCRIMINATOR: u8 = 53;
|
||||
/// Migrate discriminator.
|
||||
pub(crate) const MIGRATE_DISCRIMINATOR: u8 = 48;
|
||||
/// Resize discriminator.
|
||||
pub(crate) const RESIZE_DISCRIMINATOR: u8 = 56;
|
||||
/// Delegate discriminator.
|
||||
pub(crate) const DELEGATE_DISCRIMINATOR: u8 = 44;
|
||||
/// Revoke discriminator.
|
||||
pub(crate) const REVOKE_DISCRIMINATOR: u8 = 45;
|
||||
/// Current pre-release instruction inventory.
|
||||
pub(crate) const INSTRUCTION_ENTRIES: &[(u8, &str, bool)] = &[
|
||||
(CREATE_METADATA_ACCOUNT_DISCRIMINATOR, "create_metadata_account", true),
|
||||
(
|
||||
DEPRECATED_CREATE_MASTER_EDITION_DISCRIMINATOR,
|
||||
"deprecated_create_master_edition",
|
||||
true,
|
||||
),
|
||||
(
|
||||
DEPRECATED_MINT_NEW_EDITION_VIA_PRINTING_TOKEN_DISCRIMINATOR,
|
||||
"deprecated_mint_new_edition_from_master_edition_via_printing_token",
|
||||
true,
|
||||
),
|
||||
(UPDATE_METADATA_ACCOUNT_DISCRIMINATOR, "update_metadata_account", true),
|
||||
(
|
||||
UPDATE_PRIMARY_SALE_HAPPENED_VIA_TOKEN_DISCRIMINATOR,
|
||||
"update_primary_sale_happened_via_token",
|
||||
false,
|
||||
),
|
||||
(
|
||||
DEPRECATED_SET_RESERVATION_LIST_DISCRIMINATOR,
|
||||
"deprecated_set_reservation_list",
|
||||
true,
|
||||
),
|
||||
(
|
||||
DEPRECATED_CREATE_RESERVATION_LIST_DISCRIMINATOR,
|
||||
"deprecated_create_reservation_list",
|
||||
true,
|
||||
),
|
||||
(SIGN_METADATA_DISCRIMINATOR, "sign_metadata", false),
|
||||
(
|
||||
DEPRECATED_MINT_PRINTING_TOKENS_VIA_TOKEN_DISCRIMINATOR,
|
||||
"deprecated_mint_printing_tokens_via_token",
|
||||
true,
|
||||
),
|
||||
(
|
||||
DEPRECATED_MINT_PRINTING_TOKENS_DISCRIMINATOR,
|
||||
"deprecated_mint_printing_tokens",
|
||||
true,
|
||||
),
|
||||
(CREATE_MASTER_EDITION_DISCRIMINATOR, "create_master_edition", true),
|
||||
(PUFF_METADATA_DISCRIMINATOR, "puff_metadata", false),
|
||||
(
|
||||
MINT_NEW_EDITION_FROM_MASTER_EDITION_VIA_TOKEN_DISCRIMINATOR,
|
||||
"mint_new_edition_from_master_edition_via_token",
|
||||
false,
|
||||
),
|
||||
(
|
||||
MINT_NEW_EDITION_FROM_MASTER_EDITION_VIA_VAULT_PROXY_DISCRIMINATOR,
|
||||
"mint_new_edition_from_master_edition_via_vault_proxy",
|
||||
true,
|
||||
),
|
||||
(
|
||||
CONVERT_MASTER_EDITION_V1_TO_V2_DISCRIMINATOR,
|
||||
"convert_master_edition_v1_to_v2",
|
||||
true,
|
||||
),
|
||||
(UPDATE_METADATA_ACCOUNT_V2_DISCRIMINATOR, "update_metadata_account_v2", false),
|
||||
(CREATE_METADATA_ACCOUNT_V2_DISCRIMINATOR, "create_metadata_account_v2", true),
|
||||
(CREATE_MASTER_EDITION_V3_DISCRIMINATOR, "create_master_edition_v3", false),
|
||||
(CREATE_METADATA_ACCOUNT_V3_DISCRIMINATOR, "create_metadata_account_v3", false),
|
||||
(VERIFY_COLLECTION_DISCRIMINATOR, "verify_collection", false),
|
||||
(UNVERIFY_COLLECTION_DISCRIMINATOR, "unverify_collection", false),
|
||||
(SET_AND_VERIFY_COLLECTION_DISCRIMINATOR, "set_and_verify_collection", false),
|
||||
(
|
||||
APPROVE_COLLECTION_AUTHORITY_DISCRIMINATOR,
|
||||
"approve_collection_authority",
|
||||
false,
|
||||
),
|
||||
(REVOKE_COLLECTION_AUTHORITY_DISCRIMINATOR, "revoke_collection_authority", false),
|
||||
(
|
||||
VERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR,
|
||||
"verify_sized_collection_item",
|
||||
false,
|
||||
),
|
||||
(
|
||||
UNVERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR,
|
||||
"unverify_sized_collection_item",
|
||||
false,
|
||||
),
|
||||
(
|
||||
SET_AND_VERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR,
|
||||
"set_and_verify_sized_collection_item",
|
||||
false,
|
||||
),
|
||||
(UTILIZE_DISCRIMINATOR, "utilize", false),
|
||||
(APPROVE_USE_AUTHORITY_DISCRIMINATOR, "approve_use_authority", false),
|
||||
(REVOKE_USE_AUTHORITY_DISCRIMINATOR, "revoke_use_authority", false),
|
||||
(FREEZE_DELEGATED_ACCOUNT_DISCRIMINATOR, "freeze_delegated_account", true),
|
||||
(THAW_DELEGATED_ACCOUNT_DISCRIMINATOR, "thaw_delegated_account", true),
|
||||
(REMOVE_CREATOR_VERIFICATION_DISCRIMINATOR, "remove_creator_verification", false),
|
||||
(SET_TOKEN_STANDARD_DISCRIMINATOR, "set_token_standard", false),
|
||||
(SET_COLLECTION_SIZE_DISCRIMINATOR, "set_collection_size", false),
|
||||
(
|
||||
BUBBLEGUM_SET_COLLECTION_SIZE_DISCRIMINATOR,
|
||||
"bubblegum_set_collection_size",
|
||||
false,
|
||||
),
|
||||
(CREATE_ESCROW_ACCOUNT_DISCRIMINATOR, "create_escrow_account", false),
|
||||
(CLOSE_ESCROW_ACCOUNT_DISCRIMINATOR, "close_escrow_account", false),
|
||||
(TRANSFER_OUT_OF_ESCROW_DISCRIMINATOR, "transfer_out_of_escrow", false),
|
||||
(BURN_NFT_DISCRIMINATOR, "burn_nft", true),
|
||||
(BURN_EDITION_NFT_DISCRIMINATOR, "burn_edition_nft", true),
|
||||
(BURN_DISCRIMINATOR, "burn", false),
|
||||
(CREATE_DISCRIMINATOR, "create", false),
|
||||
(MINT_DISCRIMINATOR, "mint", false),
|
||||
(LOCK_DISCRIMINATOR, "lock", false),
|
||||
(UNLOCK_DISCRIMINATOR, "unlock", false),
|
||||
(TRANSFER_DISCRIMINATOR, "transfer", false),
|
||||
(COLLECT_DISCRIMINATOR, "collect", false),
|
||||
(PRINT_DISCRIMINATOR, "print", false),
|
||||
(UPDATE_DISCRIMINATOR, "update", false),
|
||||
(USE_DISCRIMINATOR, "use", false),
|
||||
(VERIFY_DISCRIMINATOR, "verify", false),
|
||||
(UNVERIFY_DISCRIMINATOR, "unverify", false),
|
||||
(MIGRATE_DISCRIMINATOR, "migrate", false),
|
||||
(RESIZE_DISCRIMINATOR, "resize", false),
|
||||
(CLOSE_ACCOUNTS_DISCRIMINATOR, "close_accounts", false),
|
||||
(DELEGATE_DISCRIMINATOR, "delegate", false),
|
||||
(REVOKE_DISCRIMINATOR, "revoke", false),
|
||||
];
|
||||
|
||||
/// Canonical tracing target for this decoder.
|
||||
pub(crate) const TRACING_TARGET: &str = "kb-lib.decoder.metadata.metaplex_token_metadata";
|
||||
3152
kb-lib/src/decoder/metadata/metaplex_token_metadata/decoder.rs
Normal file
3152
kb-lib/src/decoder/metadata/metaplex_token_metadata/decoder.rs
Normal file
File diff suppressed because it is too large
Load Diff
2746
kb-lib/src/decoder/metadata/metaplex_token_metadata/instruction.rs
Normal file
2746
kb-lib/src/decoder/metadata/metaplex_token_metadata/instruction.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
// file: kb-lib/src/lib.rs
|
||||
// version: 10
|
||||
// version: 11
|
||||
|
||||
//! Consolidated decoder, executor, materializer and shared model library.
|
||||
#![warn(missing_docs)]
|
||||
@@ -291,6 +291,8 @@ pub(crate) use crate::decoder::spl_token_payload_tag;
|
||||
pub use crate::decoder::ELGAMAL_REGISTRY_ACCOUNT_LEN;
|
||||
/// Parsed SPL ElGamal public-key registry account.
|
||||
pub use crate::decoder::ElGamalRegistryState;
|
||||
/// Exact decoder for the Metaplex Token Metadata program.
|
||||
pub use crate::decoder::MetadataMetaplexTokenMetadataDecoder;
|
||||
/// Exact decoder for the SPL Associated Token Account program.
|
||||
pub use crate::decoder::SplAssociatedTokenAccountDecoder;
|
||||
/// Exact decoder for the SPL ElGamal registry program.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- file: kb-program-ids/README.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# kb-program-ids
|
||||
|
||||
`kb-program-ids` est la source unique des identifiants de programmes Solana et des comptes natifs connus utilisés par le workspace.
|
||||
|
||||
La tranche `0.1.0-pre.004` expose les 18 surfaces exécutables nécessaires au décodeur Solana Core, les comptes natifs associés utilisés par leurs contrats et l’identifiant SPL Token classique employé par les tests de frontière. La tranche `0.1.0-pre.005` ajoute les trois identifiants SPL Memo v1, v3 et v4 sans les classer parmi les surfaces natives. `0.1.0-pre.006` active l’identifiant SPL Token classique dans un décodeur concret tout en le maintenant hors des surfaces natives. `0.1.0-pre.007` ajoute les identifiants SPL Associated Token Account et Token‑2022 nécessaires à la frontière ATA. `0.1.0-pre.008` ajoute le Program ID indépendant du registre ElGamal de Token‑2022, toujours hors des surfaces natives.
|
||||
La tranche `0.1.0-pre.004` expose les 18 surfaces exécutables nécessaires au décodeur Solana Core, les comptes natifs associés utilisés par leurs contrats et l’identifiant SPL Token classique employé par les tests de frontière. La tranche `0.1.0-pre.005` ajoute les trois identifiants SPL Memo v1, v3 et v4 sans les classer parmi les surfaces natives. `0.1.0-pre.006` active l’identifiant SPL Token classique dans un décodeur concret tout en le maintenant hors des surfaces natives. `0.1.0-pre.007` ajoute les identifiants SPL Associated Token Account et Token‑2022 nécessaires à la frontière ATA. `0.1.0-pre.008` ajoute le Program ID indépendant du registre ElGamal de Token‑2022. `0.1.0-pre.009` ajoute le Program ID indépendant de Metaplex Token Metadata. Ces programmes restent hors des surfaces natives.
|
||||
|
||||
`constants.rs` reste l’unique source des adresses et des tableaux statiques. `programs.rs` porte
|
||||
`ProgramIdEntry`, ses méthodes et toutes les fonctions de consultation. `lib.rs` se limite aux
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-program-ids/src/constants.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
//! Canonical Solana program and well-known account identifiers.
|
||||
|
||||
@@ -27,6 +27,9 @@ pub const INCINERATOR_PROGRAM_ID: &str = "1nc1nerator111111111111111111111111111
|
||||
pub const LOADER_V4_PROGRAM_ID: &str = "LoaderV411111111111111111111111111111111111";
|
||||
/// Native Loader program identifier.
|
||||
pub const NATIVE_LOADER_PROGRAM_ID: &str = "NativeLoader1111111111111111111111111111111";
|
||||
/// Metaplex Token Metadata program identifier.
|
||||
pub const METADATA_METAPLEX_TOKEN_METADATA_PROGRAM_ID: &str =
|
||||
"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s";
|
||||
/// Secp256k1 precompile program identifier.
|
||||
pub const SECP256K1_PROGRAM_ID: &str = "KeccakSecp256k11111111111111111111111111111";
|
||||
/// Secp256r1 precompile program identifier.
|
||||
@@ -198,6 +201,10 @@ pub(crate) const PROGRAM_ID_ENTRIES: &[crate::ProgramIdEntry] = &[
|
||||
name: "incinerator",
|
||||
address: crate::INCINERATOR_PROGRAM_ID,
|
||||
},
|
||||
crate::ProgramIdEntry {
|
||||
name: "metadata_metaplex_token_metadata",
|
||||
address: crate::METADATA_METAPLEX_TOKEN_METADATA_PROGRAM_ID,
|
||||
},
|
||||
crate::ProgramIdEntry {
|
||||
name: "loader_v4",
|
||||
address: crate::LOADER_V4_PROGRAM_ID,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-program-ids/src/lib.rs
|
||||
// version: 7
|
||||
// version: 8
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -39,6 +39,8 @@ pub use constants::FEATURE_PROGRAM_ID;
|
||||
pub use constants::INCINERATOR_PROGRAM_ID;
|
||||
/// Loader version 4 program identifier.
|
||||
pub use constants::LOADER_V4_PROGRAM_ID;
|
||||
/// Metaplex Token Metadata program identifier.
|
||||
pub use constants::METADATA_METAPLEX_TOKEN_METADATA_PROGRAM_ID;
|
||||
/// Native Loader program identifier.
|
||||
pub use constants::NATIVE_LOADER_PROGRAM_ID;
|
||||
/// Secp256k1 precompile program identifier.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-program-ids/src/programs.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Enumerable canonical program registry.
|
||||
|
||||
@@ -65,7 +65,7 @@ mod tests {
|
||||
assert!(codes.insert(entry.code()));
|
||||
assert!(program_ids.insert(entry.program_id()));
|
||||
}
|
||||
assert_eq!(crate::registered_program_ids().len(), 32);
|
||||
assert_eq!(crate::registered_program_ids().len(), 33);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -122,8 +122,8 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spl_primitives_are_registered_without_joining_native_surfaces() {
|
||||
let spl_program_ids = [
|
||||
fn protocol_primitives_are_registered_without_joining_native_surfaces() {
|
||||
let protocol_program_ids = [
|
||||
crate::SPL_MEMO_V1_PROGRAM_ID,
|
||||
crate::SPL_MEMO_V3_PROGRAM_ID,
|
||||
crate::SPL_MEMO_V4_PROGRAM_ID,
|
||||
@@ -131,8 +131,9 @@ mod tests {
|
||||
crate::SPL_TOKEN_2022_PROGRAM_ID,
|
||||
crate::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID,
|
||||
crate::ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
crate::METADATA_METAPLEX_TOKEN_METADATA_PROGRAM_ID,
|
||||
];
|
||||
for program_id in spl_program_ids {
|
||||
for program_id in protocol_program_ids {
|
||||
assert!(crate::find_registered_program_id(program_id).is_some());
|
||||
assert!(
|
||||
!crate::native_program_ids()
|
||||
|
||||
Reference in New Issue
Block a user