v0.1.0-pre.008

This commit is contained in:
2026-07-23 20:40:38 +02:00
parent f5bd8fab7f
commit 12b42a31b8
26 changed files with 6686 additions and 280 deletions

View File

@@ -1,5 +1,5 @@
# file: kb-lib/Cargo.toml
# version: 6
# version: 7
[package]
name = "kb-lib"
@@ -31,7 +31,9 @@ ts-rs.workspace = true
wincode.workspace = true
[dev-dependencies]
spl-elgamal-registry-interface.workspace = true
spl-memo-interface.workspace = true
spl-token-2022-interface.workspace = true
spl-token-interface.workspace = true
[lints]

View File

@@ -1,5 +1,5 @@
<!-- file: kb-lib/README.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# kb-lib
@@ -56,12 +56,39 @@ puis expose tout écart comme diagnostic. SPL Token classique et Token2022 so
Program ID sans reconstruire leur état ni interpréter leurs extensions. La matrice normative est
`docs/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json`.
## Décodeur SPL Token2022
`SplToken2022Decoder` couvre exclusivement
`TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`. Il conserve les 48 enveloppes de premier niveau,
les sous-instructions dextensions dont le wire est officiellement identifiable, les interfaces
Token Metadata et Token Group exécutées directement par Token2022, ainsi que `Batch` sans batch
imbriqué.
Le décodeur borne les payloads, les chaînes de metadata, le nombre denfants et les comptes
cumulés. Les comptes, autorités, offsets de preuve, suffixes et chemins outer/inner restent
ordonnés et exacts. Une transaction échouée produit une intention non commitée. Le parseur public
`parse_token_2022_state()` distingue Mint, Account et Multisig, conserve la base exacte et expose
les entrées TLV ordonnées sans inventer létat dun programme externe pointé. La matrice normative
est `docs/SPL_TOKEN_2022_MATRIX.json`.
## Décodeur du registre ElGamal
`SplElgamalRegistryDecoder` couvre le programme indépendant
`regVYJW7tcT8zipN5YiBvHsvR5jXW1uLFxaHSbugABg`. Il décode exactement `CreateRegistry` et
`UpdateRegistry`, conserve loffset relatif de preuve et ne prétend jamais vérifier la preuve ZK.
`parse_elgamal_registry_state()` exige exactement 64 octets et restitue le wallet propriétaire, la
clé publique ElGamal et le wire complet. La matrice normative est
`docs/SPL_ELGAMAL_REGISTRY_MATRIX.json`.
## API publique utile
- `SolanaCoreDecoder` : décodeur concret natif ;
- `SplMemoDecoder` : décodeur exact des trois générations SPL Memo ;
- `SplTokenDecoder` : décodeur exact du programme SPL Token classique ;
- `SplAssociatedTokenAccountDecoder` : décodeur exact du programme Associated Token Account ;
- `SplToken2022Decoder` : décodeur exact des instructions Token2022 ;
- `Token2022State`, `Token2022StateKind`, `Token2022TlvEntry` et `parse_token_2022_state()` : API publique de lecture détat Token2022 ;
- `SplElgamalRegistryDecoder`, `ElGamalRegistryState` et `parse_elgamal_registry_state()` : API publique du registre ElGamal ;
- `InstructionDecoder` : contrat de reconnaissance, couverture et décodage contextualisé ;
- `ProtocolDecoder` : contrat de compatibilité avec les observations historiques ;
- `CoreInstructionReplayInput` : input source-neutral produit par lextraction core ;

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder.rs
// version: 4
// version: 5
//! Consolidated decoder modules.
@@ -33,6 +33,8 @@ pub mod vesting;
pub mod wallet;
pub mod weighted;
/// One parsed SPL ElGamal registry instruction.
pub(crate) use self::spl::ParsedRegistryInstruction;
/// Current stable Associated Token Account decoded event contract version.
pub(crate) use self::spl::SPL_ASSOCIATED_TOKEN_ACCOUNT_EVENT_VERSION;
/// Exact Associated Token Account instructions published by the official interface.
@@ -51,6 +53,14 @@ pub(crate) use self::spl::SPL_ASSOCIATED_TOKEN_ACCOUNT_MAX_TRANSACTION_KEYS;
pub(crate) use self::spl::SPL_ASSOCIATED_TOKEN_ACCOUNT_SURFACE_CODE;
/// Canonical tracing target for the Associated Token Account decoder.
pub(crate) use self::spl::SPL_ASSOCIATED_TOKEN_ACCOUNT_TRACING_TARGET;
/// Current stable SPL ElGamal registry event contract version.
pub(crate) use self::spl::SPL_ELGAMAL_REGISTRY_EVENT_VERSION;
/// Maximum retained SPL ElGamal registry instruction payload size.
pub(crate) use self::spl::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES;
/// Stable SPL ElGamal registry surface code.
pub(crate) use self::spl::SPL_ELGAMAL_REGISTRY_SURFACE_CODE;
/// Canonical tracing target for the SPL ElGamal registry decoder.
pub(crate) use self::spl::SPL_ELGAMAL_REGISTRY_TRACING_TARGET;
/// Maximum payload prefix retained for bounded diagnostics.
pub(crate) use self::spl::SPL_MEMO_DIAGNOSTIC_PREFIX_BYTES;
/// Current stable Memo decoded event contract version.
@@ -67,6 +77,24 @@ pub(crate) use self::spl::SPL_MEMO_V1_SURFACE_CODE;
pub(crate) use self::spl::SPL_MEMO_V3_SURFACE_CODE;
/// Stable Memo v4 surface code.
pub(crate) use self::spl::SPL_MEMO_V4_SURFACE_CODE;
/// Maximum prefix retained in bounded Token-2022 diagnostics.
pub(crate) use self::spl::SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES;
/// Current stable Token-2022 decoded event contract version.
pub(crate) use self::spl::SPL_TOKEN_2022_EVENT_VERSION;
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
pub(crate) use self::spl::SPL_TOKEN_2022_INSTRUCTION_ENTRIES;
/// Maximum total account metas consumed by one Token-2022 batch.
pub(crate) use self::spl::SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS;
/// Maximum decoded sub-instructions in one Token-2022 batch.
pub(crate) use self::spl::SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS;
/// Maximum retained Token-2022 instruction payload size.
pub(crate) use self::spl::SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES;
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
pub(crate) use self::spl::SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES;
/// Stable Token-2022 surface code.
pub(crate) use self::spl::SPL_TOKEN_2022_SURFACE_CODE;
/// Canonical tracing target for the Token-2022 decoder.
pub(crate) use self::spl::SPL_TOKEN_2022_TRACING_TARGET;
/// Maximum prefix retained in bounded classic SPL Token diagnostics.
pub(crate) use self::spl::SPL_TOKEN_DIAGNOSTIC_PREFIX_BYTES;
/// Current stable classic SPL Token decoded event contract version.
@@ -89,8 +117,20 @@ pub(crate) use self::spl::spl_associated_token_account_decode;
pub(crate) use self::spl::spl_associated_token_account_entry;
/// Reads one bounded Associated Token Account payload.
pub(crate) use self::spl::spl_associated_token_account_payload;
/// Decodes one bounded SPL ElGamal registry instruction.
pub(crate) use self::spl::spl_elgamal_registry_decode;
/// Decodes one bounded SPL ElGamal registry instruction payload.
pub(crate) use self::spl::spl_elgamal_registry_decode_payload;
/// Parses one exact SPL ElGamal registry instruction.
pub(crate) use self::spl::spl_elgamal_registry_parse;
/// Decodes one bounded SPL Memo instruction.
pub(crate) use self::spl::spl_memo_decode;
/// Decodes one bounded Token-2022 instruction.
pub(crate) use self::spl::spl_token_2022_decode;
/// Returns the exact entry matching one Token-2022 tag.
pub(crate) use self::spl::spl_token_2022_entry_for_tag;
/// Returns the first byte of one retained Token-2022 payload.
pub(crate) use self::spl::spl_token_2022_payload_tag;
/// Decodes one bounded classic SPL Token instruction.
pub(crate) use self::spl::spl_token_decode;
/// Returns the published entry matching one classic SPL Token tag.
@@ -98,9 +138,27 @@ 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 byte length of one SPL ElGamal registry account.
pub use self::spl::ELGAMAL_REGISTRY_ACCOUNT_LEN;
/// Parsed SPL ElGamal public-key registry account.
pub use self::spl::ElGamalRegistryState;
/// Exact decoder for the SPL Associated Token Account program.
pub use self::spl::SplAssociatedTokenAccountDecoder;
/// Exact decoder for the SPL ElGamal registry program.
pub use self::spl::SplElgamalRegistryDecoder;
/// Exact decoder for the three registered SPL Memo generations.
pub use self::spl::SplMemoDecoder;
/// Exact decoder for the Token-2022 program.
pub use self::spl::SplToken2022Decoder;
/// Exact decoder for the classic SPL Token program.
pub use self::spl::SplTokenDecoder;
/// Parsed Token-2022 Mint, Account, or Multisig state.
pub use self::spl::Token2022State;
/// Exact Token-2022 base account state kind.
pub use self::spl::Token2022StateKind;
/// One exact Token-2022 TLV entry.
pub use self::spl::Token2022TlvEntry;
/// Parses one exact SPL ElGamal registry account.
pub use self::spl::parse_elgamal_registry_state;
/// Parses one Token-2022 Mint, Account, or Multisig state.
pub use self::spl::parse_token_2022_state;

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/spl.rs
// version: 4
// version: 5
//! `spl` decoder family.
@@ -37,6 +37,22 @@ pub(crate) use self::associated_token_account::spl_associated_token_account_deco
pub(crate) use self::associated_token_account::spl_associated_token_account_entry;
/// Reads one bounded Associated Token Account payload.
pub(crate) use self::associated_token_account::spl_associated_token_account_payload;
/// One parsed SPL ElGamal registry instruction.
pub(crate) use self::elgamal_registry::ParsedRegistryInstruction;
/// Current stable SPL ElGamal registry event contract version.
pub(crate) use self::elgamal_registry::SPL_ELGAMAL_REGISTRY_EVENT_VERSION;
/// Maximum retained SPL ElGamal registry instruction payload size.
pub(crate) use self::elgamal_registry::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES;
/// Stable SPL ElGamal registry surface code.
pub(crate) use self::elgamal_registry::SPL_ELGAMAL_REGISTRY_SURFACE_CODE;
/// Canonical tracing target for the SPL ElGamal registry decoder.
pub(crate) use self::elgamal_registry::SPL_ELGAMAL_REGISTRY_TRACING_TARGET;
/// Decodes one bounded SPL ElGamal registry instruction.
pub(crate) use self::elgamal_registry::spl_elgamal_registry_decode;
/// Decodes one bounded SPL ElGamal registry instruction payload.
pub(crate) use self::elgamal_registry::spl_elgamal_registry_decode_payload;
/// Parses one exact SPL ElGamal registry instruction.
pub(crate) use self::elgamal_registry::spl_elgamal_registry_parse;
/// Maximum payload prefix retained for bounded diagnostics.
pub(crate) use self::memo::SPL_MEMO_DIAGNOSTIC_PREFIX_BYTES;
/// Current stable Memo decoded event contract version.
@@ -77,10 +93,52 @@ pub(crate) use self::token::spl_token_decode;
pub(crate) use self::token::spl_token_entry_for_tag;
/// Returns the first byte of one retained classic SPL Token payload.
pub(crate) use self::token::spl_token_payload_tag;
/// Maximum prefix retained in bounded Token-2022 diagnostics.
pub(crate) use self::token_2022::SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES;
/// Current stable Token-2022 decoded event contract version.
pub(crate) use self::token_2022::SPL_TOKEN_2022_EVENT_VERSION;
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
pub(crate) use self::token_2022::SPL_TOKEN_2022_INSTRUCTION_ENTRIES;
/// Maximum total account metas consumed by one Token-2022 batch.
pub(crate) use self::token_2022::SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS;
/// Maximum decoded sub-instructions in one Token-2022 batch.
pub(crate) use self::token_2022::SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS;
/// Maximum retained Token-2022 instruction payload size.
pub(crate) use self::token_2022::SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES;
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
pub(crate) use self::token_2022::SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES;
/// Stable Token-2022 surface code.
pub(crate) use self::token_2022::SPL_TOKEN_2022_SURFACE_CODE;
/// Canonical tracing target for the Token-2022 decoder.
pub(crate) use self::token_2022::SPL_TOKEN_2022_TRACING_TARGET;
/// Decodes one bounded Token-2022 instruction.
pub(crate) use self::token_2022::spl_token_2022_decode;
/// Returns the exact entry matching one Token-2022 tag.
pub(crate) use self::token_2022::spl_token_2022_entry_for_tag;
/// Returns the first byte of one retained Token-2022 payload.
pub(crate) use self::token_2022::spl_token_2022_payload_tag;
/// Exact decoder for the SPL Associated Token Account program.
pub use self::associated_token_account::SplAssociatedTokenAccountDecoder;
/// Exact byte length of one SPL ElGamal registry account.
pub use self::elgamal_registry::ELGAMAL_REGISTRY_ACCOUNT_LEN;
/// Parsed SPL ElGamal public-key registry account.
pub use self::elgamal_registry::ElGamalRegistryState;
/// Exact decoder for the SPL ElGamal registry program.
pub use self::elgamal_registry::SplElgamalRegistryDecoder;
/// Parses one exact SPL ElGamal registry account.
pub use self::elgamal_registry::parse_elgamal_registry_state;
/// Exact decoder for the three registered SPL Memo generations.
pub use self::memo::SplMemoDecoder;
/// Exact decoder for the classic SPL Token program.
pub use self::token::SplTokenDecoder;
/// Exact decoder for the Token-2022 program.
pub use self::token_2022::SplToken2022Decoder;
/// Parsed Token-2022 Mint, Account, or Multisig state.
pub use self::token_2022::Token2022State;
/// Exact Token-2022 base account state kind.
pub use self::token_2022::Token2022StateKind;
/// One exact Token-2022 TLV entry.
pub use self::token_2022::Token2022TlvEntry;
/// Parses one Token-2022 Mint, Account, or Multisig state.
pub use self::token_2022::parse_token_2022_state;

View File

@@ -1,10 +1,35 @@
// file: kb-lib/src/decoder/spl/elgamal_registry.rs
// version: 1
// version: 2
//! Migration boundary for legacy crate `kb_decoder_spl_elgamal_registry`.
//! Exact SPL Token-2022 ElGamal public-key registry decoder component.
/// Legacy crate name retained for migration and compatibility tracking.
pub const LEGACY_CRATE: &str = "kb_decoder_spl_elgamal_registry";
mod constants;
mod decoder;
mod state;
mod wire;
/// Current porting status.
pub const MIGRATION_STATUS: &str = "source-preserved-pending-port";
/// Current stable SPL ElGamal registry event contract version.
pub(crate) use self::constants::SPL_ELGAMAL_REGISTRY_EVENT_VERSION;
/// Maximum retained SPL ElGamal registry instruction payload size.
pub(crate) use self::constants::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES;
/// Stable SPL ElGamal registry surface code.
pub(crate) use self::constants::SPL_ELGAMAL_REGISTRY_SURFACE_CODE;
/// Canonical tracing target for the SPL ElGamal registry decoder.
pub(crate) use self::constants::SPL_ELGAMAL_REGISTRY_TRACING_TARGET;
/// One parsed SPL ElGamal registry instruction.
pub(crate) use self::wire::ParsedRegistryInstruction;
/// Decodes one bounded SPL ElGamal registry instruction.
pub(crate) use self::wire::spl_elgamal_registry_decode;
/// Decodes one bounded SPL ElGamal registry instruction payload.
pub(crate) use self::wire::spl_elgamal_registry_decode_payload;
/// Parses one exact SPL ElGamal registry instruction.
pub(crate) use self::wire::spl_elgamal_registry_parse;
/// Exact decoder for the SPL ElGamal registry program.
pub use self::decoder::SplElgamalRegistryDecoder;
/// Exact byte length of one SPL ElGamal registry account.
pub use self::state::ELGAMAL_REGISTRY_ACCOUNT_LEN;
/// Parsed SPL ElGamal public-key registry account.
pub use self::state::ElGamalRegistryState;
/// Parses one exact SPL ElGamal registry account.
pub use self::state::parse_elgamal_registry_state;

View File

@@ -0,0 +1,11 @@
// file: kb-lib/src/decoder/spl/elgamal_registry/constants.rs
// version: 1
//! Constants for the SPL ElGamal registry decoder.
pub(crate) const SPL_ELGAMAL_REGISTRY_SURFACE_CODE: &str = "spl_elgamal_registry";
pub(crate) const SPL_ELGAMAL_REGISTRY_EVENT_VERSION: u32 = 1;
pub(crate) const SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES: usize = 16;
/// Canonical tracing target for this crate.
pub(crate) const SPL_ELGAMAL_REGISTRY_TRACING_TARGET: &str = "kb-lib.decoder.spl.elgamal_registry";

View File

@@ -0,0 +1,246 @@
// file: kb-lib/src/decoder/spl/elgamal_registry/decoder.rs
// version: 1
//! Exact dispatch for the SPL ElGamal registry program.
const SURFACES: &[crate::DecoderSurface] = &[crate::DecoderSurface {
program_id: kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID,
surface_code: crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE,
priority: 100,
}];
const PROGRAM_IDS: &[&str] = &[kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID];
/// Decoder for the dedicated Token-2022 ElGamal public-key registry program.
#[derive(Clone, Debug, Default)]
pub struct SplElgamalRegistryDecoder;
impl crate::ProtocolDecoder for crate::SplElgamalRegistryDecoder {
fn decoder_name(&self) -> &'static str {
return "kb_decoder_spl_elgamal_registry";
}
fn decoder_version(&self) -> &'static str {
return env!("CARGO_PKG_VERSION");
}
fn program_ids(&self) -> &'static [&'static str] {
return PROGRAM_IDS;
}
fn supports_observation(
&self,
observation: &crate::ProgramObservation,
) -> crate::DecoderSupport {
return if crate::ProtocolDecoder::handles_program_id(self, &observation.program_id) {
crate::DecoderSupport::Yes
} else {
crate::DecoderSupport::No
};
}
fn decode_observation(
&self,
_observation: &crate::ProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::DecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}
impl crate::InstructionDecoder for crate::SplElgamalRegistryDecoder {
fn identity(&self) -> crate::DecoderIdentity {
return crate::DecoderIdentity {
name: "spl_elgamal_registry".to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
};
}
fn surfaces(&self) -> &'static [crate::DecoderSurface] {
return SURFACES;
}
fn coverage(&self) -> std::vec::Vec<crate::DecoderCoverageDeclaration> {
return [(0_u8, "create_registry"), (1_u8, "update_registry")]
.into_iter()
.map(|(tag, code)| {
return crate::DecoderCoverageDeclaration {
program_id: kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID
.to_string(),
surface_code: std::option::Option::Some(
crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE.to_string(),
),
entry_kind: crate::DecoderCoverageEntryKind::Instruction,
entry_code: code.to_string(),
discriminator_hex: std::option::Option::Some(format!("{tag:02x}")),
historical: false,
};
})
.collect();
}
fn recognize(&self, input: &crate::CoreInstructionReplayInput) -> crate::DecoderRecognition {
if input.program_id != kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID {
return crate::DecoderRecognition::incompatible();
}
let entry = input
.instruction_payload_json
.as_ref()
.and_then(|payload| return payload.get("dataBase64"))
.and_then(serde_json::Value::as_str)
.and_then(|encoded| {
use base64::Engine; // rust-rules: trait-import
return base64::engine::general_purpose::STANDARD.decode(encoded.as_bytes()).ok();
})
.and_then(|bytes| return bytes.first().copied())
.and_then(|tag| {
return match tag {
0 => std::option::Option::Some("create_registry".to_string()),
1 => std::option::Option::Some("update_registry".to_string()),
_ => std::option::Option::None,
};
});
return crate::DecoderRecognition::compatible(
entry.is_some(),
100,
std::option::Option::Some(crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE.to_string()),
entry,
std::option::Option::None,
);
}
fn decode(&self, input: &crate::CoreInstructionReplayInput) -> crate::DecoderExecutionResult {
if input.program_id != kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID {
return crate::DecoderExecutionResult::unsupported(std::option::Option::None);
}
let result = crate::spl_elgamal_registry_decode(input);
if matches!(
result.status,
crate::DecoderOutcomeStatus::Failed | crate::DecoderOutcomeStatus::Unsupported
) {
tracing::error!(
target: crate::SPL_ELGAMAL_REGISTRY_TRACING_TARGET,
action = "decode_failure",
signature = %input.signature,
slot = input.slot,
instruction_path = %input.instruction_path,
program_id = %input.program_id,
processor_name = "spl_elgamal_registry",
processor_version = env!("CARGO_PKG_VERSION"),
input_key = %input.replay_input_key,
payload_hash = ?input.instruction_payload_hash,
transaction_failed = input.transaction_failed,
result_status = ?result.status,
diagnostics = ?result.diagnostics,
"SPL ElGamal registry instruction was not decoded successfully"
);
}
tracing::debug!(
target: crate::SPL_ELGAMAL_REGISTRY_TRACING_TARGET,
action = "decode",
signature = %input.signature,
instruction_path = %input.instruction_path,
program_id = %input.program_id,
transaction_failed = input.transaction_failed,
result_status = ?result.status,
observation_count = result.observations.len(),
"SPL ElGamal registry instruction decode completed"
);
return result;
}
}
#[cfg(test)]
mod tests {
use base64::Engine; // rust-rules: trait-import
fn input(
program_id: &str,
payload: &[u8],
failed: bool,
path: &str,
) -> crate::CoreInstructionReplayInput {
let result = crate::CoreInstructionReplayInput::new(
format!("signature:{path}"),
"signature",
42,
path,
program_id,
failed,
if failed {
std::option::Option::Some(serde_json::json!({"InstructionError":[0,"Custom"]}))
} else {
std::option::Option::None
},
serde_json::json!([]),
serde_json::json!([]),
std::option::Option::Some(serde_json::json!({
"dataBase64": base64::engine::general_purpose::STANDARD.encode(payload)
})),
std::option::Option::None,
serde_json::json!([]),
serde_json::json!([]),
serde_json::json!([]),
serde_json::json!([]),
);
return match result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("registry replay input failed: {error}"),
};
}
#[test]
fn exact_program_boundary_and_interface_id_are_preserved() {
assert_eq!(
spl_elgamal_registry_interface::id().to_string(),
kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID
);
let decoder = crate::SplElgamalRegistryDecoder;
assert_eq!(crate::InstructionDecoder::coverage(&decoder).len(), 2);
let foreign = input(kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID, &[0, 1], false, "0");
assert_eq!(
crate::InstructionDecoder::decode(&decoder, &foreign).status,
crate::DecoderOutcomeStatus::Unsupported
);
}
#[test]
fn create_and_update_decode_exact_offsets_and_commit_state() {
for (tag, code, offset, failed, path) in [
(0_u8, "create_registry", 1_i8, false, "0"),
(1_u8, "update_registry", -1_i8, true, "1/0"),
(1_u8, "update_registry", 0_i8, false, "2"),
] {
let input = input(
kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID,
&[tag, offset as u8],
failed,
path,
);
let result =
crate::InstructionDecoder::decode(&crate::SplElgamalRegistryDecoder, &input);
assert_eq!(result.status, crate::DecoderOutcomeStatus::Decoded);
assert_eq!(result.recognized_entry_code.as_deref(), std::option::Option::Some(code));
assert_eq!(
result.observations[0].payload_json["proofInstructionOffset"],
serde_json::json!(offset)
);
assert_eq!(result.observations[0].observation_committed, !failed);
}
}
#[test]
fn malformed_unknown_and_suffixed_wire_fail_closed() {
for payload in [std::vec::Vec::new(), vec![0], vec![2, 0], vec![0, 1, 2]] {
let input = input(
kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID,
payload.as_slice(),
false,
"0",
);
let result =
crate::InstructionDecoder::decode(&crate::SplElgamalRegistryDecoder, &input);
assert_eq!(result.status, crate::DecoderOutcomeStatus::Failed);
assert!(result.observations.is_empty());
}
}
}

View File

@@ -0,0 +1,76 @@
// file: kb-lib/src/decoder/spl/elgamal_registry/state.rs
// version: 1
//! Strict SPL ElGamal registry account-state parsing.
use base64::Engine; // rust-rules: trait-import
/// Exact byte length of one SPL ElGamal registry account.
pub const ELGAMAL_REGISTRY_ACCOUNT_LEN: usize = 64;
/// Public state retained by one SPL ElGamal registry account.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ElGamalRegistryState {
/// Wallet address associated with this registry.
pub owner: String,
/// Exact 32-byte ElGamal public key encoded as standard base64.
pub elgamal_pubkey_base64: String,
/// Exact account bytes encoded as lowercase hexadecimal.
pub wire_hex: String,
}
/// Parse one exact SPL ElGamal registry account.
pub fn parse_elgamal_registry_state(
data: &[u8],
) -> std::result::Result<ElGamalRegistryState, std::string::String> {
if data.len() != ELGAMAL_REGISTRY_ACCOUNT_LEN {
return std::result::Result::Err(format!(
"SPL ElGamal registry account requires exactly {ELGAMAL_REGISTRY_ACCOUNT_LEN} bytes; received {}",
data.len()
));
}
return std::result::Result::Ok(ElGamalRegistryState {
owner: bs58::encode(&data[..32]).into_string(),
elgamal_pubkey_base64: base64::engine::general_purpose::STANDARD.encode(&data[32..64]),
wire_hex: lower_hex(data),
});
}
fn lower_hex(bytes: &[u8]) -> String {
let mut output = String::with_capacity(bytes.len() * 2);
for byte in bytes {
output.push_str(&format!("{byte:02x}"));
}
return output;
}
#[cfg(test)]
mod tests {
use base64::Engine; // rust-rules: trait-import
#[test]
fn exact_registry_state_preserves_owner_key_and_wire() {
let mut data = [0u8; crate::ELGAMAL_REGISTRY_ACCOUNT_LEN];
data[..32].fill(7);
data[32..].fill(9);
let parsed = crate::parse_elgamal_registry_state(&data);
assert_eq!(
parsed.as_ref().map(|state| return state.owner.clone()),
std::result::Result::Ok(bs58::encode([7u8; 32]).into_string())
);
assert_eq!(
parsed.as_ref().map(|state| return state.elgamal_pubkey_base64.clone()),
std::result::Result::Ok(base64::engine::general_purpose::STANDARD.encode([9u8; 32]))
);
assert_eq!(
parsed.as_ref().map(|state| return state.wire_hex.len()),
std::result::Result::Ok(128)
);
}
#[test]
fn registry_state_rejects_every_non_exact_length() {
assert!(crate::parse_elgamal_registry_state(&[0; 63]).is_err());
assert!(crate::parse_elgamal_registry_state(&[0; 65]).is_err());
}
}

View File

@@ -0,0 +1,195 @@
// file: kb-lib/src/decoder/spl/elgamal_registry/wire.rs
// version: 1
//! Exact two-byte SPL ElGamal registry instruction decoding.
use base64::Engine; // rust-rules: trait-import
use sha2::Digest; // rust-rules: trait-import
#[derive(Clone, Debug)]
pub(crate) struct ParsedRegistryInstruction {
pub(crate) code: &'static str,
pub(crate) tag: u8,
pub(crate) proof_instruction_offset: i8,
}
pub(crate) fn spl_elgamal_registry_decode_payload(
input: &crate::CoreInstructionReplayInput,
) -> std::result::Result<std::vec::Vec<u8>, std::string::String> {
let payload = match input.instruction_payload_json.as_ref() {
std::option::Option::Some(value) => value,
std::option::Option::None => {
return std::result::Result::Err(
"ElGamal registry instruction payload is not retained".to_string(),
);
},
};
let encoded = match payload.get("dataBase64").and_then(serde_json::Value::as_str) {
std::option::Option::Some(value) => value,
std::option::Option::None => {
return std::result::Result::Err(
"ElGamal registry payload does not contain dataBase64".to_string(),
);
},
};
if encoded.len() > 32 {
return std::result::Result::Err(
"ElGamal registry base64 payload is too large".to_string(),
);
}
let bytes = match base64::engine::general_purpose::STANDARD.decode(encoded.as_bytes()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(format!(
"ElGamal registry payload is not valid base64: {error}"
));
},
};
if bytes.len() > crate::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES {
return std::result::Result::Err(format!(
"ElGamal registry payload exceeds {} bytes",
crate::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES
));
}
return std::result::Result::Ok(bytes);
}
pub(crate) fn spl_elgamal_registry_parse(
bytes: &[u8],
) -> std::result::Result<crate::ParsedRegistryInstruction, std::string::String> {
if bytes.len() != 2 {
return std::result::Result::Err(format!(
"ElGamal registry instruction requires exactly 2 bytes; received {}",
bytes.len()
));
}
let code = match bytes[0] {
0 => "create_registry",
1 => "update_registry",
tag => return std::result::Result::Err(format!("unknown ElGamal registry tag {tag}")),
};
return std::result::Result::Ok(crate::ParsedRegistryInstruction {
code,
tag: bytes[0],
proof_instruction_offset: bytes[1] as i8,
});
}
pub(crate) fn spl_elgamal_registry_decode(
input: &crate::CoreInstructionReplayInput,
) -> crate::DecoderExecutionResult {
let bytes = match crate::spl_elgamal_registry_decode_payload(input) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(message) => {
return crate::DecoderExecutionResult {
status: crate::DecoderOutcomeStatus::Failed,
recognized_entry_code: std::option::Option::None,
observations: std::vec::Vec::new(),
diagnostics: std::vec![crate::DecoderDiagnostic {
code: "elgamal_registry_payload_invalid".to_string(),
message,
retriable: false,
}],
};
},
};
let parsed = match crate::spl_elgamal_registry_parse(bytes.as_slice()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(message) => {
return crate::DecoderExecutionResult {
status: crate::DecoderOutcomeStatus::Failed,
recognized_entry_code: bytes.first().and_then(|tag| {
return match tag {
0 => std::option::Option::Some("create_registry".to_string()),
1 => std::option::Option::Some("update_registry".to_string()),
_ => std::option::Option::None,
};
}),
observations: std::vec::Vec::new(),
diagnostics: std::vec![crate::DecoderDiagnostic {
code: "elgamal_registry_wire_invalid".to_string(),
message,
retriable: false,
}],
};
},
};
let committed = !input.transaction_failed;
let wire_hash = hash(bytes.as_slice());
let event = crate::DecodedProtocolEvent {
signature: crate::Signature(input.signature.clone()),
slot: crate::Slot(input.slot),
instruction_path: crate::InstructionPath(input.instruction_path.clone()),
program_id: crate::ProgramId(input.program_id.clone()),
protocol_code: crate::ProtocolCode(crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE.to_string()),
surface_code: crate::SurfaceCode(crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE.to_string()),
event_code: crate::EventCode(format!(
"{}.{}",
crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE,
parsed.code
)),
event_name: crate::EventName(parsed.code.to_string()),
event_family: crate::EventFamily::Admin,
source_kind: if input.instruction_path.contains('/') {
crate::EventSourceKind::InnerInstruction
} else {
crate::EventSourceKind::Instruction
},
confidence: crate::DecoderConfidence::ManualExact,
};
let observation = crate::DecodedObservation {
event_key: format!("elgamal_registry:{}:0", parsed.code),
event,
payload_json: serde_json::json!({
"eventVersion": crate::SPL_ELGAMAL_REGISTRY_EVENT_VERSION,
"instruction": parsed.code,
"wireTag": parsed.tag,
"proofInstructionOffset": parsed.proof_instruction_offset,
"proofLocationKind": if parsed.proof_instruction_offset == 0 { "context_state_account" } else { "relative_instruction_offset" },
"instructionPath": input.instruction_path,
"instructionLocation": if input.instruction_path.contains('/') { "inner" } else { "outer" },
"transactionSucceeded": !input.transaction_failed,
"committed": committed,
"accounts": input.instruction_accounts_json,
"wire": {
"lengthBytes": bytes.len(),
"sha256": wire_hash,
"prefixHex": hex(bytes.as_slice()),
"complete": true,
},
"programBoundary": {
"registryProgramId": kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID,
"token2022ProgramId": kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID,
"zkProofProgramId": kb_program_ids::ZK_ELGAMAL_PROOF_PROGRAM_ID,
"proofDecodedHere": false,
}
}),
transaction_failed: input.transaction_failed,
transaction_error: input.transaction_err_json.clone(),
observation_committed: committed,
proof: crate::DecoderProof {
kind: crate::DecoderProofKind::Manual,
confidence: crate::DecoderConfidence::ManualExact,
evidence: std::vec![
"spl_elgamal_registry_interface_0_2_1_registry_instruction_unpack".to_string(),
format!("wire_tag:{}", parsed.tag),
format!("wire_sha256:{wire_hash}"),
],
},
};
return crate::DecoderExecutionResult {
status: crate::DecoderOutcomeStatus::Decoded,
recognized_entry_code: std::option::Option::Some(parsed.code.to_string()),
observations: std::vec![observation],
diagnostics: std::vec::Vec::new(),
};
}
fn hash(bytes: &[u8]) -> std::string::String {
let digest = sha2::Sha256::digest(bytes);
return digest.iter().map(|byte| return format!("{byte:02x}")).collect();
}
fn hex(bytes: &[u8]) -> std::string::String {
return bytes.iter().map(|byte| return format!("{byte:02x}")).collect();
}

View File

@@ -1,10 +1,45 @@
// file: kb-lib/src/decoder/spl/token_2022.rs
// version: 1
// version: 2
//! Migration boundary for legacy crate `kb_decoder_spl_token_2022`.
//! Exact Token-2022 instruction and state decoder component.
/// Legacy crate name retained for migration and compatibility tracking.
pub const LEGACY_CRATE: &str = "kb_decoder_spl_token_2022";
mod constants;
mod decoder;
mod state;
mod wire;
/// Current porting status.
pub const MIGRATION_STATUS: &str = "source-preserved-pending-port";
/// Maximum prefix retained in bounded Token-2022 diagnostics.
pub(crate) use self::constants::SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES;
/// Current stable Token-2022 decoded event contract version.
pub(crate) use self::constants::SPL_TOKEN_2022_EVENT_VERSION;
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
pub(crate) use self::constants::SPL_TOKEN_2022_INSTRUCTION_ENTRIES;
/// Maximum total account metas consumed by one Token-2022 batch.
pub(crate) use self::constants::SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS;
/// Maximum decoded sub-instructions in one Token-2022 batch.
pub(crate) use self::constants::SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS;
/// Maximum retained Token-2022 instruction payload size.
pub(crate) use self::constants::SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES;
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
pub(crate) use self::constants::SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES;
/// Stable Token-2022 surface code.
pub(crate) use self::constants::SPL_TOKEN_2022_SURFACE_CODE;
/// Canonical tracing target for the Token-2022 decoder.
pub(crate) use self::constants::SPL_TOKEN_2022_TRACING_TARGET;
/// Decodes one bounded Token-2022 instruction.
pub(crate) use self::wire::spl_token_2022_decode;
/// Returns the exact entry matching one Token-2022 tag.
pub(crate) use self::wire::spl_token_2022_entry_for_tag;
/// Returns the first byte of one retained Token-2022 payload.
pub(crate) use self::wire::spl_token_2022_payload_tag;
/// Exact decoder for the Token-2022 program.
pub use self::decoder::SplToken2022Decoder;
/// Parsed Token-2022 Mint, Account, or Multisig state.
pub use self::state::Token2022State;
/// Exact Token-2022 base account state kind.
pub use self::state::Token2022StateKind;
/// One exact Token-2022 TLV entry.
pub use self::state::Token2022TlvEntry;
/// Parses one Token-2022 Mint, Account, or Multisig state.
pub use self::state::parse_token_2022_state;

View File

@@ -0,0 +1,72 @@
// file: kb-lib/src/decoder/spl/token_2022/constants.rs
// version: 1
//! Local constants for the exact Token-2022 decoder. Program identifiers live in `kb_program_ids`.
/// Stable Token-2022 surface code.
pub(crate) const SPL_TOKEN_2022_SURFACE_CODE: &str = "spl_token_2022";
/// Current decoded event contract version.
pub(crate) const SPL_TOKEN_2022_EVENT_VERSION: u32 = 1;
/// Maximum retained instruction payload size.
pub(crate) const SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES: usize = 16_384;
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
pub(crate) const SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES: usize = 4_096;
/// Maximum prefix retained in diagnostics.
pub(crate) const SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES: usize = 32;
/// Maximum decoded sub-instructions in one batch.
pub(crate) const SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS: usize = 64;
/// Maximum total account metas consumed by one batch.
pub(crate) const SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS: usize = 512;
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
pub(crate) const SPL_TOKEN_2022_INSTRUCTION_ENTRIES: &[(u8, &str, bool)] = &[
(0, "initialize_mint", false),
(1, "initialize_account", false),
(2, "initialize_multisig", false),
(3, "transfer", false),
(4, "approve", false),
(5, "revoke", false),
(6, "set_authority", false),
(7, "mint_to", false),
(8, "burn", false),
(9, "close_account", false),
(10, "freeze_account", false),
(11, "thaw_account", false),
(12, "transfer_checked", false),
(13, "approve_checked", false),
(14, "mint_to_checked", false),
(15, "burn_checked", false),
(16, "initialize_account2", false),
(17, "sync_native", false),
(18, "initialize_account3", false),
(19, "initialize_multisig2", false),
(20, "initialize_mint2", false),
(21, "get_account_data_size", false),
(22, "initialize_immutable_owner", false),
(23, "amount_to_ui_amount", false),
(24, "ui_amount_to_amount", false),
(25, "initialize_mint_close_authority", false),
(26, "transfer_fee_extension", false),
(27, "confidential_transfer_extension", false),
(28, "default_account_state_extension", false),
(29, "reallocate", false),
(30, "memo_transfer_extension", false),
(31, "create_native_mint", false),
(32, "initialize_non_transferable_mint", false),
(33, "interest_bearing_mint_extension", false),
(34, "cpi_guard_extension", false),
(35, "initialize_permanent_delegate", false),
(36, "transfer_hook_extension", false),
(37, "confidential_transfer_fee_extension", false),
(38, "withdraw_excess_lamports", false),
(39, "metadata_pointer_extension", false),
(40, "group_pointer_extension", false),
(41, "group_member_pointer_extension", false),
(42, "confidential_mint_burn_extension", false),
(43, "scaled_ui_amount_extension", false),
(44, "pausable_extension", false),
(45, "unwrap_lamports", false),
(46, "permissioned_burn_extension", false),
(255, "batch", false),
];
/// Canonical tracing target for this crate.
pub(crate) const SPL_TOKEN_2022_TRACING_TARGET: &str = "kb-lib.decoder.spl.token_2022";

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/lib.rs
// version: 9
// version: 10
//! Consolidated decoder, executor, materializer and shared model library.
#![warn(missing_docs)]
@@ -11,6 +11,8 @@ pub mod executor;
pub mod materializer;
pub mod model;
/// One parsed SPL ElGamal registry instruction.
pub(crate) use crate::decoder::ParsedRegistryInstruction;
/// Current stable Associated Token Account decoded event contract version.
pub(crate) use crate::decoder::SPL_ASSOCIATED_TOKEN_ACCOUNT_EVENT_VERSION;
/// Exact Associated Token Account instructions published by the official interface.
@@ -29,6 +31,14 @@ pub(crate) use crate::decoder::SPL_ASSOCIATED_TOKEN_ACCOUNT_MAX_TRANSACTION_KEYS
pub(crate) use crate::decoder::SPL_ASSOCIATED_TOKEN_ACCOUNT_SURFACE_CODE;
/// Canonical tracing target for the Associated Token Account decoder.
pub(crate) use crate::decoder::SPL_ASSOCIATED_TOKEN_ACCOUNT_TRACING_TARGET;
/// Current stable SPL ElGamal registry event contract version.
pub(crate) use crate::decoder::SPL_ELGAMAL_REGISTRY_EVENT_VERSION;
/// Maximum retained SPL ElGamal registry instruction payload size.
pub(crate) use crate::decoder::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES;
/// Stable SPL ElGamal registry surface code.
pub(crate) use crate::decoder::SPL_ELGAMAL_REGISTRY_SURFACE_CODE;
/// Canonical tracing target for the SPL ElGamal registry decoder.
pub(crate) use crate::decoder::SPL_ELGAMAL_REGISTRY_TRACING_TARGET;
/// Maximum payload prefix retained for bounded Memo diagnostics.
pub(crate) use crate::decoder::SPL_MEMO_DIAGNOSTIC_PREFIX_BYTES;
/// Current stable Memo decoded event contract version.
@@ -45,6 +55,24 @@ pub(crate) use crate::decoder::SPL_MEMO_V1_SURFACE_CODE;
pub(crate) use crate::decoder::SPL_MEMO_V3_SURFACE_CODE;
/// Stable Memo v4 surface code.
pub(crate) use crate::decoder::SPL_MEMO_V4_SURFACE_CODE;
/// Maximum prefix retained in bounded Token-2022 diagnostics.
pub(crate) use crate::decoder::SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES;
/// Current stable Token-2022 decoded event contract version.
pub(crate) use crate::decoder::SPL_TOKEN_2022_EVENT_VERSION;
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
pub(crate) use crate::decoder::SPL_TOKEN_2022_INSTRUCTION_ENTRIES;
/// Maximum total account metas consumed by one Token-2022 batch.
pub(crate) use crate::decoder::SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS;
/// Maximum decoded sub-instructions in one Token-2022 batch.
pub(crate) use crate::decoder::SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS;
/// Maximum retained Token-2022 instruction payload size.
pub(crate) use crate::decoder::SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES;
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
pub(crate) use crate::decoder::SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES;
/// Stable Token-2022 surface code.
pub(crate) use crate::decoder::SPL_TOKEN_2022_SURFACE_CODE;
/// Canonical tracing target for the Token-2022 decoder.
pub(crate) use crate::decoder::SPL_TOKEN_2022_TRACING_TARGET;
/// Maximum prefix retained in bounded classic SPL Token diagnostics.
pub(crate) use crate::decoder::SPL_TOKEN_DIAGNOSTIC_PREFIX_BYTES;
/// Current stable classic SPL Token decoded event contract version.
@@ -89,43 +117,6 @@ pub(crate) use crate::decoder::solana::SOLANA_CORE_NATIVE_EVENT_VERSION;
pub(crate) use crate::decoder::solana::SOLANA_CORE_NATIVE_LOADER_SURFACE_CODE;
/// Maximum number of component bytes retained as a hexadecimal event prefix.
pub(crate) use crate::decoder::solana::SOLANA_CORE_PRECOMPILE_COMPONENT_PREFIX_BYTES;
/// Expected role and privileges for one positional instruction account.
pub(crate) use crate::decoder::solana::SolanaCoreAccountRole;
/// Returns declared Address Lookup Table instruction coverage.
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_coverage;
/// Decodes one Address Lookup Table instruction.
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_decode;
/// Recognizes one Address Lookup Table instruction without producing an event.
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_recognize;
/// Returns declared Compute Budget instruction coverage.
pub(crate) use crate::decoder::solana::solana_core_compute_budget_coverage;
/// Decodes one Compute Budget instruction.
pub(crate) use crate::decoder::solana::solana_core_compute_budget_decode;
/// Recognizes one Compute Budget instruction without producing an event.
pub(crate) use crate::decoder::solana::solana_core_compute_budget_recognize;
/// Returns declared Config Program instruction coverage.
pub(crate) use crate::decoder::solana::solana_core_config_coverage;
/// Decodes one generic Config Program store instruction.
pub(crate) use crate::decoder::solana::solana_core_config_decode;
/// Recognizes one generic Config Program store instruction.
pub(crate) use crate::decoder::solana::solana_core_config_recognize;
/// Resolves positional instruction accounts and validates their core indexes.
pub(crate) use crate::decoder::solana::solana_core_resolve_accounts;
/// Decodes one bounded Associated Token Account instruction.
pub(crate) use crate::decoder::spl_associated_token_account_decode;
/// Returns the exact entry matching an Associated Token Account wire.
pub(crate) use crate::decoder::spl_associated_token_account_entry;
/// Reads one bounded Associated Token Account payload.
pub(crate) use crate::decoder::spl_associated_token_account_payload;
/// Decodes one bounded SPL Memo instruction.
pub(crate) use crate::decoder::spl_memo_decode;
/// Decodes one bounded classic SPL Token instruction.
pub(crate) use crate::decoder::spl_token_decode;
/// Returns the published entry matching one classic SPL Token tag.
pub(crate) use crate::decoder::spl_token_entry_for_tag;
/// Returns the first byte of one retained classic SPL Token payload.
pub(crate) use crate::decoder::spl_token_payload_tag;
/// Stable protocol code shared by native Solana events.
pub(crate) use crate::decoder::solana::SOLANA_CORE_PROTOCOL_CODE;
/// Byte length of a secp256k1 Ethereum address.
@@ -158,12 +149,32 @@ pub(crate) use crate::decoder::solana::SOLANA_CORE_VOTE_SURFACE_CODE;
pub(crate) use crate::decoder::solana::SOLANA_CORE_ZK_ELGAMAL_PROOF_SURFACE_CODE;
/// Stable historical ZK Token Proof surface code.
pub(crate) use crate::decoder::solana::SOLANA_CORE_ZK_TOKEN_PROOF_SURFACE_CODE;
/// Expected role and privileges for one positional instruction account.
pub(crate) use crate::decoder::solana::SolanaCoreAccountRole;
/// One resolved outer instruction payload and its provenance relative to the target instruction.
pub(crate) use crate::decoder::solana::SolanaCoreResolvedInstructionPayload;
/// Returns declared Address Lookup Table instruction coverage.
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_coverage;
/// Decodes one Address Lookup Table instruction.
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_decode;
/// Recognizes one Address Lookup Table instruction without producing an event.
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_recognize;
/// Returns a hexadecimal prefix no longer than the available byte slice.
pub(crate) use crate::decoder::solana::solana_core_bounded_hexadecimal_prefix;
/// Extracts one exact bounded byte slice with checked arithmetic.
pub(crate) use crate::decoder::solana::solana_core_bounded_slice;
/// Returns declared Compute Budget instruction coverage.
pub(crate) use crate::decoder::solana::solana_core_compute_budget_coverage;
/// Decodes one Compute Budget instruction.
pub(crate) use crate::decoder::solana::solana_core_compute_budget_decode;
/// Recognizes one Compute Budget instruction without producing an event.
pub(crate) use crate::decoder::solana::solana_core_compute_budget_recognize;
/// Returns declared Config Program instruction coverage.
pub(crate) use crate::decoder::solana::solana_core_config_coverage;
/// Decodes one generic Config Program store instruction.
pub(crate) use crate::decoder::solana::solana_core_config_decode;
/// Recognizes one generic Config Program store instruction.
pub(crate) use crate::decoder::solana::solana_core_config_recognize;
/// Decodes one retained base64 instruction payload with an explicit byte limit.
pub(crate) use crate::decoder::solana::solana_core_decode_instruction_data;
/// Returns the decoded target payload length when retained and valid.
@@ -202,6 +213,8 @@ pub(crate) use crate::decoder::solana::solana_core_precompiles_recognize;
pub(crate) use crate::decoder::solana::solana_core_read_u32_le;
/// Reads one little-endian `u64` from an exact byte range.
pub(crate) use crate::decoder::solana::solana_core_read_u64_le;
/// Resolves positional instruction accounts and validates their core indexes.
pub(crate) use crate::decoder::solana::solana_core_resolve_accounts;
/// Resolves a secp256k1 instruction reference. The runtime format has no current-instruction
/// sentinel: every `u8` value is an explicit outer instruction index.
pub(crate) use crate::decoder::solana::solana_core_resolve_u8_instruction_payload;
@@ -247,13 +260,53 @@ pub(crate) use crate::decoder::solana::solana_core_zk_token_proof_coverage;
pub(crate) use crate::decoder::solana::solana_core_zk_token_proof_decode;
/// Recognizes one historical ZK Token Proof layout or the current no-op runtime fallback.
pub(crate) use crate::decoder::solana::solana_core_zk_token_proof_recognize;
/// Decodes one bounded Associated Token Account instruction.
pub(crate) use crate::decoder::spl_associated_token_account_decode;
/// Returns the exact entry matching an Associated Token Account wire.
pub(crate) use crate::decoder::spl_associated_token_account_entry;
/// Reads one bounded Associated Token Account payload.
pub(crate) use crate::decoder::spl_associated_token_account_payload;
/// Decodes one bounded SPL ElGamal registry instruction.
pub(crate) use crate::decoder::spl_elgamal_registry_decode;
/// Decodes one bounded SPL ElGamal registry instruction payload.
pub(crate) use crate::decoder::spl_elgamal_registry_decode_payload;
/// Parses one exact SPL ElGamal registry instruction.
pub(crate) use crate::decoder::spl_elgamal_registry_parse;
/// Decodes one bounded SPL Memo instruction.
pub(crate) use crate::decoder::spl_memo_decode;
/// Decodes one bounded Token-2022 instruction.
pub(crate) use crate::decoder::spl_token_2022_decode;
/// Returns the exact entry matching one Token-2022 tag.
pub(crate) use crate::decoder::spl_token_2022_entry_for_tag;
/// Returns the first byte of one retained Token-2022 payload.
pub(crate) use crate::decoder::spl_token_2022_payload_tag;
/// Decodes one bounded classic SPL Token instruction.
pub(crate) use crate::decoder::spl_token_decode;
/// Returns the published entry matching one classic SPL Token tag.
pub(crate) use crate::decoder::spl_token_entry_for_tag;
/// Returns the first byte of one retained classic SPL Token payload.
pub(crate) use crate::decoder::spl_token_payload_tag;
/// Exact byte length of one SPL ElGamal registry account.
pub use crate::decoder::ELGAMAL_REGISTRY_ACCOUNT_LEN;
/// Parsed SPL ElGamal public-key registry account.
pub use crate::decoder::ElGamalRegistryState;
/// Exact decoder for the SPL Associated Token Account program.
pub use crate::decoder::SplAssociatedTokenAccountDecoder;
/// Exact decoder for the SPL ElGamal registry program.
pub use crate::decoder::SplElgamalRegistryDecoder;
/// Exact decoder for the three registered SPL Memo generations.
pub use crate::decoder::SplMemoDecoder;
/// Exact decoder for the Token-2022 program.
pub use crate::decoder::SplToken2022Decoder;
/// Exact decoder for the classic SPL Token program.
pub use crate::decoder::SplTokenDecoder;
/// Parsed Token-2022 Mint, Account, or Multisig state.
pub use crate::decoder::Token2022State;
/// Exact Token-2022 base account state kind.
pub use crate::decoder::Token2022StateKind;
/// One exact Token-2022 TLV entry.
pub use crate::decoder::Token2022TlvEntry;
/// Current contextual core instruction input contract version.
pub use crate::decoder::api::contracts::CORE_INSTRUCTION_INPUT_CONTRACT_VERSION;
/// Stable contextual decoded observation.
@@ -294,6 +347,10 @@ pub use crate::decoder::api::decoder::DecoderSupport;
pub use crate::decoder::api::decoder::InitialDecoder;
/// Exposes the common protocol decoder trait.
pub use crate::decoder::api::decoder::ProtocolDecoder;
/// Parses one exact SPL ElGamal registry account.
pub use crate::decoder::parse_elgamal_registry_state;
/// Parses one Token-2022 Mint, Account, or Multisig state.
pub use crate::decoder::parse_token_2022_state;
/// Runtime-native Solana decoder with maximal native instruction coverage.
pub use crate::decoder::solana::SolanaCoreDecoder;
/// Exposes the blockhash policy kind.