v0.1.0-pre.021

This commit is contained in:
2026-07-24 22:52:37 +02:00
parent 4190b2c0ce
commit 34f96582bc
14 changed files with 2317 additions and 88 deletions

View File

@@ -1,5 +1,5 @@
# file: Cargo.toml # file: Cargo.toml
# version: 1 # version: 2
[workspace] [workspace]
resolver = "3" resolver = "3"
@@ -27,7 +27,7 @@ publish = false
[workspace.dependencies] [workspace.dependencies]
argon2 = { version = "^0.5", features = ["std", "zeroize"] } argon2 = { version = "^0.5", features = ["std", "zeroize"] }
async-trait = { version = "^0.1", features = [] } async-trait = { version = "^0.1", features = [] }
base64 = { version = "^0.22", features = [] } base64 = { version = "^0.23", features = [] }
bytemuck = { version = "^1.25", features = ["derive"] } bytemuck = { version = "^1.25", features = ["derive"] }
borsh_0_10 = { package = "borsh", version = "^0.10" } borsh_0_10 = { package = "borsh", version = "^0.10" }
borsh = { version = "^1.7", features = ["ascii", "bson", "bytes", "default", "derive", "de_strict_order", "borsh-derive", "indexmap", "std", "rc"] } borsh = { version = "^1.7", features = ["ascii", "bson", "bytes", "default", "derive", "de_strict_order", "borsh-derive", "indexmap", "std", "rc"] }

View File

@@ -39,7 +39,7 @@
"kb-lib.executor.spl.memo", "kb-lib.executor.spl.memo",
"kb_executor_spl_noop", "kb_executor_spl_noop",
"kb_executor_spl_single_pool", "kb_executor_spl_single_pool",
"kb_executor_spl_token", "kb-lib.executor.spl.token",
"kb-lib.executor.spl.token2022", "kb-lib.executor.spl.token2022",
"kb-logging", "kb-logging",
"kb-lib.materializer.admin", "kb-lib.materializer.admin",
@@ -576,42 +576,42 @@
] ]
}, },
{ {
"name": "file_kb_executor_spl_token_debug", "name": "file_kb_lib_executor_spl_token_debug",
"enabled": true, "enabled": true,
"sink": "file", "sink": "file",
"level": "debug", "level": "debug",
"path": "logs/devnet/kb_executor_spl_token/debug.log", "path": "logs/devnet/kb_lib_executor_spl_token/debug.log",
"rotation": "daily", "rotation": "daily",
"format": "human", "format": "human",
"ansi": false, "ansi": false,
"targets": [ "targets": [
"kb_executor_spl_token" "kb-lib.executor.spl.token"
] ]
}, },
{ {
"name": "file_kb_executor_spl_token_info", "name": "file_kb_lib_executor_spl_token_info",
"enabled": true, "enabled": true,
"sink": "file", "sink": "file",
"level": "info", "level": "info",
"path": "logs/devnet/kb_executor_spl_token/info.log", "path": "logs/devnet/kb_lib_executor_spl_token/info.log",
"rotation": "daily", "rotation": "daily",
"format": "human", "format": "human",
"ansi": false, "ansi": false,
"targets": [ "targets": [
"kb_executor_spl_token" "kb-lib.executor.spl.token"
] ]
}, },
{ {
"name": "file_kb_executor_spl_token_error", "name": "file_kb_lib_executor_spl_token_error",
"enabled": true, "enabled": true,
"sink": "file", "sink": "file",
"level": "error", "level": "error",
"path": "logs/devnet/kb_executor_spl_token/error.jsonl", "path": "logs/devnet/kb_lib_executor_spl_token/error.jsonl",
"rotation": "daily", "rotation": "daily",
"format": "json", "format": "json",
"ansi": false, "ansi": false,
"targets": [ "targets": [
"kb_executor_spl_token" "kb-lib.executor.spl.token"
] ]
}, },
{ {
@@ -1680,7 +1680,7 @@
"kb-lib.executor.spl.memo", "kb-lib.executor.spl.memo",
"kb_executor_spl_noop", "kb_executor_spl_noop",
"kb_executor_spl_single_pool", "kb_executor_spl_single_pool",
"kb_executor_spl_token", "kb-lib.executor.spl.token",
"kb-lib.executor.spl.token2022", "kb-lib.executor.spl.token2022",
"kb-logging", "kb-logging",
"kb-lib.materializer.admin", "kb-lib.materializer.admin",
@@ -2217,42 +2217,42 @@
] ]
}, },
{ {
"name": "file_kb_executor_spl_token_debug", "name": "file_kb_lib_executor_spl_token_debug",
"enabled": true, "enabled": true,
"sink": "file", "sink": "file",
"level": "debug", "level": "debug",
"path": "logs/mainnet_research/kb_executor_spl_token/debug.log", "path": "logs/mainnet_research/kb_lib_executor_spl_token/debug.log",
"rotation": "daily", "rotation": "daily",
"format": "human", "format": "human",
"ansi": false, "ansi": false,
"targets": [ "targets": [
"kb_executor_spl_token" "kb-lib.executor.spl.token"
] ]
}, },
{ {
"name": "file_kb_executor_spl_token_info", "name": "file_kb_lib_executor_spl_token_info",
"enabled": true, "enabled": true,
"sink": "file", "sink": "file",
"level": "info", "level": "info",
"path": "logs/mainnet_research/kb_executor_spl_token/info.log", "path": "logs/mainnet_research/kb_lib_executor_spl_token/info.log",
"rotation": "daily", "rotation": "daily",
"format": "human", "format": "human",
"ansi": false, "ansi": false,
"targets": [ "targets": [
"kb_executor_spl_token" "kb-lib.executor.spl.token"
] ]
}, },
{ {
"name": "file_kb_executor_spl_token_error", "name": "file_kb_lib_executor_spl_token_error",
"enabled": true, "enabled": true,
"sink": "file", "sink": "file",
"level": "error", "level": "error",
"path": "logs/mainnet_research/kb_executor_spl_token/error.jsonl", "path": "logs/mainnet_research/kb_lib_executor_spl_token/error.jsonl",
"rotation": "daily", "rotation": "daily",
"format": "json", "format": "json",
"ansi": false, "ansi": false,
"targets": [ "targets": [
"kb_executor_spl_token" "kb-lib.executor.spl.token"
] ]
}, },
{ {
@@ -3521,7 +3521,7 @@
"kb-lib.executor.spl.memo", "kb-lib.executor.spl.memo",
"kb_executor_spl_noop", "kb_executor_spl_noop",
"kb_executor_spl_single_pool", "kb_executor_spl_single_pool",
"kb_executor_spl_token", "kb-lib.executor.spl.token",
"kb-lib.executor.spl.token2022", "kb-lib.executor.spl.token2022",
"kb-logging", "kb-logging",
"kb-lib.materializer.admin", "kb-lib.materializer.admin",
@@ -4058,42 +4058,42 @@
] ]
}, },
{ {
"name": "file_kb_executor_spl_token_debug", "name": "file_kb_lib_executor_spl_token_debug",
"enabled": true, "enabled": true,
"sink": "file", "sink": "file",
"level": "debug", "level": "debug",
"path": "logs/mainnet/kb_executor_spl_token/debug.log", "path": "logs/mainnet/kb_lib_executor_spl_token/debug.log",
"rotation": "daily", "rotation": "daily",
"format": "human", "format": "human",
"ansi": false, "ansi": false,
"targets": [ "targets": [
"kb_executor_spl_token" "kb-lib.executor.spl.token"
] ]
}, },
{ {
"name": "file_kb_executor_spl_token_info", "name": "file_kb_lib_executor_spl_token_info",
"enabled": true, "enabled": true,
"sink": "file", "sink": "file",
"level": "info", "level": "info",
"path": "logs/mainnet/kb_executor_spl_token/info.log", "path": "logs/mainnet/kb_lib_executor_spl_token/info.log",
"rotation": "daily", "rotation": "daily",
"format": "human", "format": "human",
"ansi": false, "ansi": false,
"targets": [ "targets": [
"kb_executor_spl_token" "kb-lib.executor.spl.token"
] ]
}, },
{ {
"name": "file_kb_executor_spl_token_error", "name": "file_kb_lib_executor_spl_token_error",
"enabled": true, "enabled": true,
"sink": "file", "sink": "file",
"level": "error", "level": "error",
"path": "logs/mainnet/kb_executor_spl_token/error.jsonl", "path": "logs/mainnet/kb_lib_executor_spl_token/error.jsonl",
"rotation": "daily", "rotation": "daily",
"format": "json", "format": "json",
"ansi": false, "ansi": false,
"targets": [ "targets": [
"kb_executor_spl_token" "kb-lib.executor.spl.token"
] ]
}, },
{ {

View File

@@ -0,0 +1,31 @@
# Audit de migration de `kb-lib`
## État après `0.1.0-pre.021`
Linventaire des anciennes crates métier de `khadhroony-bot2` a été comparé à larborescence consolidée de `khadhroony-bot3/kb-lib`.
### Implémentations fonctionnelles migrées
- modèles et contrats publics de décodage, matérialisation et exécution ;
- décodeur Solana Core ;
- décodeurs SPL Memo, Token classique, ATA, Token-2022 et ElGamal Registry ;
- décodeur Metaplex Token Metadata dans létat intermédiaire atteint par bot2 `0.4.7` ;
- matérialisateurs transaction annotations, token accounts, admin, risk, fees, lifecycle, metadata, staking et compliance audit ;
- exécuteurs Solana Core, SPL Memo v4, SPL Token classique, ATA, Token-2022 et ElGamal Registry ;
- politique de sécurité commune des exécuteurs.
### Éléments encore à migrer dans `kb-lib`
Il reste une ancienne crate fonctionnelle :
- `kb_execution_solana` : assemblage de transactions legacy, durable nonce, validation des comptes nonce, signature, preuves de simulation et contrôle de taille de paquet.
Cette couche nest pas un exécuteur de programme. Elle doit être portée sous la famille `executor/solana` avant la migration du transport on-chain.
### Éléments volontairement réservés
Les autres modules de décodeurs, matérialisateurs et exécuteurs présents dans bot3 correspondent aux placeholders réservés de bot2. Ils ne contiennent pas dimplémentation fonctionnelle perdue à migrer.
### Étape suivante
Migrer `kb_execution_solana`, vérifier ses contrats publics et ses tests, puis clôturer la parité de `kb-lib` avant de passer à la future crate de transport on-chain.

View File

@@ -1,5 +1,5 @@
# file: kb-lib/Cargo.toml # file: kb-lib/Cargo.toml
# version: 12 # version: 13
[package] [package]
name = "kb-lib" name = "kb-lib"
@@ -39,6 +39,7 @@ spl-token-group-interface.workspace = true
spl-token-metadata-interface.workspace = true spl-token-metadata-interface.workspace = true
spl-token-2022-interface.workspace = true spl-token-2022-interface.workspace = true
spl-token-confidential-transfer-proof-extraction.workspace = true spl-token-confidential-transfer-proof-extraction.workspace = true
spl-token-interface.workspace = true
spl-memo-interface.workspace = true spl-memo-interface.workspace = true
tracing.workspace = true tracing.workspace = true
ts-rs.workspace = true ts-rs.workspace = true
@@ -48,7 +49,6 @@ wincode.workspace = true
solana-ed25519-program.workspace = true solana-ed25519-program.workspace = true
solana-secp256k1-program.workspace = true solana-secp256k1-program.workspace = true
solana-secp256r1-program.workspace = true solana-secp256r1-program.workspace = true
spl-token-interface.workspace = true
[lints] [lints]
workspace = true workspace = true

View File

@@ -511,6 +511,56 @@ pub use self::spl::EX_SPL_MEMO_ADD_MEMO_OPERATION;
pub use self::spl::EX_SPL_MEMO_MAX_MESSAGE_BYTES; pub use self::spl::EX_SPL_MEMO_MAX_MESSAGE_BYTES;
/// Exposes the SPL Memo signer bound. /// Exposes the SPL Memo signer bound.
pub use self::spl::EX_SPL_MEMO_MAX_SIGNERS; pub use self::spl::EX_SPL_MEMO_MAX_SIGNERS;
/// Exposes `EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_APPROVE_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_APPROVE_OPERATION;
/// Exposes `EX_SPL_TOKEN_BATCH_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_BATCH_OPERATION;
/// Exposes `EX_SPL_TOKEN_BURN_CHECKED_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_BURN_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_BURN_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_BURN_OPERATION;
/// Exposes `EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION;
/// Exposes `EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_MINT_TO_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_MINT_TO_OPERATION;
/// Exposes `EX_SPL_TOKEN_REVOKE_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_REVOKE_OPERATION;
/// Exposes `EX_SPL_TOKEN_SET_AUTHORITY_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_SET_AUTHORITY_OPERATION;
/// Exposes `EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES`.
pub use self::spl::EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES;
/// Exposes `EX_SPL_TOKEN_SYNC_NATIVE_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_SYNC_NATIVE_OPERATION;
/// Exposes `EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_TRANSFER_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_TRANSFER_OPERATION;
/// Exposes `EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION;
/// Exposes `EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION;
/// Exposes `EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION`. /// Exposes `EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION`.
pub use self::spl::EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION; pub use self::spl::EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION`. /// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION`.
@@ -721,6 +771,18 @@ pub use self::spl::ExSplAssociatedTokenAccountExecutor;
pub use self::spl::ExSplAssociatedTokenAccountOperation; pub use self::spl::ExSplAssociatedTokenAccountOperation;
/// Exposes the exact Token Program used by ATA derivation. /// Exposes the exact Token Program used by ATA derivation.
pub use self::spl::ExSplAssociatedTokenProgram; pub use self::spl::ExSplAssociatedTokenProgram;
/// Exposes `ExSplClassicTokenAmount`.
pub use self::spl::ExSplClassicTokenAmount;
/// Exposes `ExSplClassicTokenAuthority`.
pub use self::spl::ExSplClassicTokenAuthority;
/// Exposes `ExSplClassicTokenAuthorityType`.
pub use self::spl::ExSplClassicTokenAuthorityType;
/// Exposes `ExSplClassicTokenExecutionIntent`.
pub use self::spl::ExSplClassicTokenExecutionIntent;
/// Exposes `ExSplClassicTokenOperation`.
pub use self::spl::ExSplClassicTokenOperation;
/// Exposes `ExSplClassicTokenSingleOperation`.
pub use self::spl::ExSplClassicTokenSingleOperation;
/// Exposes the typed SPL ElGamal registry execution intent. /// Exposes the typed SPL ElGamal registry execution intent.
pub use self::spl::ExSplElgamalRegistryExecutionIntent; pub use self::spl::ExSplElgamalRegistryExecutionIntent;
/// Exposes the typed SPL ElGamal registry executor. /// Exposes the typed SPL ElGamal registry executor.
@@ -860,6 +922,14 @@ pub(crate) use self::solana::executor_solana_core_validate_seeded_address;
pub(crate) use self::solana::executor_solana_core_vote_build_prepared_plan; pub(crate) use self::solana::executor_solana_core_vote_build_prepared_plan;
/// Crate-root access to `build_prepared_plan` from `zk_elgamal`. /// Crate-root access to `build_prepared_plan` from `zk_elgamal`.
pub(crate) use self::solana::executor_solana_core_zk_elgamal_build_prepared_plan; pub(crate) use self::solana::executor_solana_core_zk_elgamal_build_prepared_plan;
/// Crate-root access to `EX_SPL_TOKEN_MAX_BATCH_ACCOUNTS`.
pub(crate) use self::spl::EX_SPL_TOKEN_MAX_BATCH_ACCOUNTS;
/// Crate-root access to `EX_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS`.
pub(crate) use self::spl::EX_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS;
/// Crate-root access to `EX_SPL_TOKEN_MAX_MULTISIG_SIGNERS`.
pub(crate) use self::spl::EX_SPL_TOKEN_MAX_MULTISIG_SIGNERS;
/// Crate-root access to `EX_SPL_TOKEN_MAX_UI_AMOUNT_BYTES`.
pub(crate) use self::spl::EX_SPL_TOKEN_MAX_UI_AMOUNT_BYTES;
/// Maximum ordered multisig signer occurrences for SPL Token-2022. /// Maximum ordered multisig signer occurrences for SPL Token-2022.
pub(crate) use self::spl::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS; pub(crate) use self::spl::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS;
/// Maximum transfer-fee source account count for SPL Token-2022. /// Maximum transfer-fee source account count for SPL Token-2022.
@@ -872,6 +942,8 @@ pub(crate) use self::spl::TRACING_TARGET_EXECUTOR_SPL_ATA;
pub(crate) use self::spl::TRACING_TARGET_EXECUTOR_SPL_ELGAMAL_REGISTRY; pub(crate) use self::spl::TRACING_TARGET_EXECUTOR_SPL_ELGAMAL_REGISTRY;
/// Canonical SPL Memo tracing target. /// Canonical SPL Memo tracing target.
pub(crate) use self::spl::TRACING_TARGET_EXECUTOR_SPL_MEMO; pub(crate) use self::spl::TRACING_TARGET_EXECUTOR_SPL_MEMO;
/// Crate-root access to `TRACING_TARGET_EXECUTOR_SPL_TOKEN`.
pub(crate) use self::spl::TRACING_TARGET_EXECUTOR_SPL_TOKEN;
/// Canonical SPL Token-2022 tracing target. /// Canonical SPL Token-2022 tracing target.
pub(crate) use self::spl::TRACING_TARGET_EXECUTOR_SPL_TOKEN2022; pub(crate) use self::spl::TRACING_TARGET_EXECUTOR_SPL_TOKEN2022;
/// Internal SPL ATA plan builder. /// Internal SPL ATA plan builder.
@@ -880,6 +952,8 @@ pub(crate) use self::spl::executor_spl_ata_build_prepared_plan;
pub(crate) use self::spl::executor_spl_elgamal_registry_build_prepared_plan; pub(crate) use self::spl::executor_spl_elgamal_registry_build_prepared_plan;
/// Internal SPL Memo plan builder. /// Internal SPL Memo plan builder.
pub(crate) use self::spl::executor_spl_memo_build_prepared_plan; pub(crate) use self::spl::executor_spl_memo_build_prepared_plan;
/// Crate-root access to `executor_spl_token_build_prepared_plan`.
pub(crate) use self::spl::executor_spl_token_build_prepared_plan;
/// Internal SPL Token-2022 prepared-plan builder. /// Internal SPL Token-2022 prepared-plan builder.
pub(crate) use self::spl::executor_spl_token2022_build_prepared_plan; pub(crate) use self::spl::executor_spl_token2022_build_prepared_plan;
@@ -887,7 +961,7 @@ pub(crate) use self::spl::executor_spl_token2022_build_prepared_plan;
mod reserved_executor_tests { mod reserved_executor_tests {
#[test] #[test]
fn every_reserved_executor_is_registered_and_builds_only_an_empty_plan() { fn every_reserved_executor_is_registered_and_builds_only_an_empty_plan() {
let executors: [&dyn crate::ExApiInstructionExecutor; 99] = [ let executors: [&dyn crate::ExApiInstructionExecutor; 98] = [
&crate::ExAdapterSaberDecimalWrapperExecutor, &crate::ExAdapterSaberDecimalWrapperExecutor,
&crate::ExAdminJupiterLockExecutor, &crate::ExAdminJupiterLockExecutor,
&crate::ExAdminPumpFeesExecutor, &crate::ExAdminPumpFeesExecutor,
@@ -969,7 +1043,6 @@ mod reserved_executor_tests {
&crate::ExSplNoopExecutor, &crate::ExSplNoopExecutor,
&crate::ExSplSinglePoolExecutor, &crate::ExSplSinglePoolExecutor,
&crate::ExSplStakePoolExecutor, &crate::ExSplStakePoolExecutor,
&crate::ExSplTokenExecutor,
&crate::ExStableSwapHyloExchangeExecutor, &crate::ExStableSwapHyloExchangeExecutor,
&crate::ExStableSwapJupiterStableExecutor, &crate::ExStableSwapJupiterStableExecutor,
&crate::ExStableSwapNumeraireExecutor, &crate::ExStableSwapNumeraireExecutor,
@@ -988,7 +1061,7 @@ mod reserved_executor_tests {
&crate::ExWalletJupiterApeproSmartWalletExecutor, &crate::ExWalletJupiterApeproSmartWalletExecutor,
&crate::ExWeightedSwapStabbleExecutor, &crate::ExWeightedSwapStabbleExecutor,
]; ];
assert_eq!(executors.len(), 99); assert_eq!(executors.len(), 98);
for executor in executors { for executor in executors {
assert!(!executor.program_ids().is_empty()); assert!(!executor.program_ids().is_empty());
for program_id in executor.program_ids() { for program_id in executor.program_ids() {

View File

@@ -65,7 +65,69 @@ pub use self::noop::ExSplNoopExecutor;
pub use self::single_pool::ExSplSinglePoolExecutor; pub use self::single_pool::ExSplSinglePoolExecutor;
/// Exposes the reserved `spl/stake_pool` executor. /// Exposes the reserved `spl/stake_pool` executor.
pub use self::stake_pool::ExSplStakePoolExecutor; pub use self::stake_pool::ExSplStakePoolExecutor;
/// Exposes the reserved `spl/token` executor. /// Exposes `EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION`.
pub use self::token::EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION`.
pub use self::token::EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_APPROVE_OPERATION`.
pub use self::token::EX_SPL_TOKEN_APPROVE_OPERATION;
/// Exposes `EX_SPL_TOKEN_BATCH_OPERATION`.
pub use self::token::EX_SPL_TOKEN_BATCH_OPERATION;
/// Exposes `EX_SPL_TOKEN_BURN_CHECKED_OPERATION`.
pub use self::token::EX_SPL_TOKEN_BURN_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_BURN_OPERATION`.
pub use self::token::EX_SPL_TOKEN_BURN_OPERATION;
/// Exposes `EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION`.
pub use self::token::EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION`.
pub use self::token::EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION`.
pub use self::token::EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION`.
pub use self::token::EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION`.
pub use self::token::EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION`.
pub use self::token::EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION`.
pub use self::token::EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION;
/// Exposes `EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION`.
pub use self::token::EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_MINT_TO_OPERATION`.
pub use self::token::EX_SPL_TOKEN_MINT_TO_OPERATION;
/// Exposes `EX_SPL_TOKEN_REVOKE_OPERATION`.
pub use self::token::EX_SPL_TOKEN_REVOKE_OPERATION;
/// Exposes `EX_SPL_TOKEN_SET_AUTHORITY_OPERATION`.
pub use self::token::EX_SPL_TOKEN_SET_AUTHORITY_OPERATION;
/// Exposes `EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES`.
pub use self::token::EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES;
/// Exposes `EX_SPL_TOKEN_SYNC_NATIVE_OPERATION`.
pub use self::token::EX_SPL_TOKEN_SYNC_NATIVE_OPERATION;
/// Exposes `EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION`.
pub use self::token::EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION`.
pub use self::token::EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_TRANSFER_OPERATION`.
pub use self::token::EX_SPL_TOKEN_TRANSFER_OPERATION;
/// Exposes `EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION`.
pub use self::token::EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION`.
pub use self::token::EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION;
/// Exposes `EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION`.
pub use self::token::EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION;
/// Exposes `ExSplClassicTokenAmount`.
pub use self::token::ExSplClassicTokenAmount;
/// Exposes `ExSplClassicTokenAuthority`.
pub use self::token::ExSplClassicTokenAuthority;
/// Exposes `ExSplClassicTokenAuthorityType`.
pub use self::token::ExSplClassicTokenAuthorityType;
/// Exposes `ExSplClassicTokenExecutionIntent`.
pub use self::token::ExSplClassicTokenExecutionIntent;
/// Exposes `ExSplClassicTokenOperation`.
pub use self::token::ExSplClassicTokenOperation;
/// Exposes `ExSplClassicTokenSingleOperation`.
pub use self::token::ExSplClassicTokenSingleOperation;
/// Exposes the SPL Token classic executor.
pub use self::token::ExSplTokenExecutor; pub use self::token::ExSplTokenExecutor;
/// Exposes `EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION`. /// Exposes `EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION`.
pub use self::token2022::EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION; pub use self::token2022::EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION;
@@ -320,6 +382,18 @@ pub(crate) use self::elgamal_registry::executor_spl_elgamal_registry_build_prepa
pub(crate) use self::memo::TRACING_TARGET_EXECUTOR_SPL_MEMO; pub(crate) use self::memo::TRACING_TARGET_EXECUTOR_SPL_MEMO;
/// Internal SPL Memo plan builder. /// Internal SPL Memo plan builder.
pub(crate) use self::memo::executor_spl_memo_build_prepared_plan; pub(crate) use self::memo::executor_spl_memo_build_prepared_plan;
/// Crate-root access to `EX_SPL_TOKEN_MAX_BATCH_ACCOUNTS`.
pub(crate) use self::token::EX_SPL_TOKEN_MAX_BATCH_ACCOUNTS;
/// Crate-root access to `EX_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS`.
pub(crate) use self::token::EX_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS;
/// Crate-root access to `EX_SPL_TOKEN_MAX_MULTISIG_SIGNERS`.
pub(crate) use self::token::EX_SPL_TOKEN_MAX_MULTISIG_SIGNERS;
/// Crate-root access to `EX_SPL_TOKEN_MAX_UI_AMOUNT_BYTES`.
pub(crate) use self::token::EX_SPL_TOKEN_MAX_UI_AMOUNT_BYTES;
/// Crate-root access to `TRACING_TARGET_EXECUTOR_SPL_TOKEN`.
pub(crate) use self::token::TRACING_TARGET_EXECUTOR_SPL_TOKEN;
/// Crate-root access to `executor_spl_token_build_prepared_plan`.
pub(crate) use self::token::executor_spl_token_build_prepared_plan;
/// Maximum ordered multisig signer occurrences for SPL Token-2022. /// Maximum ordered multisig signer occurrences for SPL Token-2022.
pub(crate) use self::token2022::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS; pub(crate) use self::token2022::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS;
/// Maximum transfer-fee source account count for SPL Token-2022. /// Maximum transfer-fee source account count for SPL Token-2022.

View File

@@ -1,49 +1,87 @@
// file: kb-lib/src/executor/spl/token.rs // file: kb-lib/src/executor/spl/token.rs
// version: 2 // version: 3
//! Reserved executor for `spl_token`. //! SPL Token classic executor.
/// Reserved executor for the `spl_token` program surface. mod builder;
#[derive(Clone, Debug, Default)] mod constants;
pub struct ExSplTokenExecutor; mod executor;
mod intent;
impl crate::ExApiInstructionExecutor for crate::ExSplTokenExecutor { /// Exposes `ExSplTokenExecutor`.
fn executor_name(&self) -> &'static str { pub use self::executor::ExSplTokenExecutor;
return "kb_executor_spl_token"; /// Exposes `EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION`.
} pub use self::intent::EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_APPROVE_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_APPROVE_OPERATION;
/// Exposes `EX_SPL_TOKEN_BATCH_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_BATCH_OPERATION;
/// Exposes `EX_SPL_TOKEN_BURN_CHECKED_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_BURN_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_BURN_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_BURN_OPERATION;
/// Exposes `EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION;
/// Exposes `EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_MINT_TO_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_MINT_TO_OPERATION;
/// Exposes `EX_SPL_TOKEN_REVOKE_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_REVOKE_OPERATION;
/// Exposes `EX_SPL_TOKEN_SET_AUTHORITY_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_SET_AUTHORITY_OPERATION;
/// Exposes `EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES`.
pub use self::intent::EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES;
/// Exposes `EX_SPL_TOKEN_SYNC_NATIVE_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_SYNC_NATIVE_OPERATION;
/// Exposes `EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_TRANSFER_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_TRANSFER_OPERATION;
/// Exposes `EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION;
/// Exposes `EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION;
/// Exposes `ExSplClassicTokenAmount`.
pub use self::intent::ExSplClassicTokenAmount;
/// Exposes `ExSplClassicTokenAuthority`.
pub use self::intent::ExSplClassicTokenAuthority;
/// Exposes `ExSplClassicTokenAuthorityType`.
pub use self::intent::ExSplClassicTokenAuthorityType;
/// Exposes `ExSplClassicTokenExecutionIntent`.
pub use self::intent::ExSplClassicTokenExecutionIntent;
/// Exposes `ExSplClassicTokenOperation`.
pub use self::intent::ExSplClassicTokenOperation;
/// Exposes `ExSplClassicTokenSingleOperation`.
pub use self::intent::ExSplClassicTokenSingleOperation;
fn executor_version(&self) -> &'static str { /// Crate-root access to `executor_spl_token_build_prepared_plan`.
return env!("CARGO_PKG_VERSION"); pub(crate) use self::builder::executor_spl_token_build_prepared_plan;
} /// Crate-root access to `EX_SPL_TOKEN_MAX_BATCH_ACCOUNTS`.
pub(crate) use self::constants::EX_SPL_TOKEN_MAX_BATCH_ACCOUNTS;
fn program_ids(&self) -> &'static [&'static str] { /// Crate-root access to `EX_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS`.
return &[kb_program_ids::SPL_TOKEN_PROGRAM_ID]; pub(crate) use self::constants::EX_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS;
} /// Crate-root access to `EX_SPL_TOKEN_MAX_MULTISIG_SIGNERS`.
pub(crate) use self::constants::EX_SPL_TOKEN_MAX_MULTISIG_SIGNERS;
fn supports_request( /// Crate-root access to `EX_SPL_TOKEN_MAX_UI_AMOUNT_BYTES`.
&self, pub(crate) use self::constants::EX_SPL_TOKEN_MAX_UI_AMOUNT_BYTES;
request: &crate::ExApiExecutionRequest, /// Crate-root access to `TRACING_TARGET_EXECUTOR_SPL_TOKEN`.
) -> crate::ExApiExecutionSupport { pub(crate) use self::constants::TRACING_TARGET_EXECUTOR_SPL_TOKEN;
if crate::ExApiInstructionExecutor::handles_program_id(self, &request.program_id) {
return crate::ExApiExecutionSupport::Maybe;
}
return crate::ExApiExecutionSupport::No;
}
fn build_plan(
&self,
_request: &crate::ExApiExecutionRequest,
) -> kb_core::Result<crate::ExApiExecutionPlan> {
let payload_json = match crate::executor_api_serialize_payload_json(
&serde_json::json!({"status":"reserved_executor","surface":"spl_token"}),
) {
std::result::Result::Ok(serialized) => serialized,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
return std::result::Result::Ok(crate::ExApiExecutionPlan {
executor_name: "kb_executor_spl_token".to_string(),
instruction_count: 0,
payload_json,
});
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
// file: kb-lib/src/executor/spl/token/constants.rs
// version: 3
//! Local constants for the SPL Token classic executor. Program identifiers live in `kb_program_ids`.
/// Maximum number of children accepted by one Batch plan.
pub(crate) const EX_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS: usize = 64;
/// Maximum aggregate account-meta occurrences accepted by one Batch plan.
pub(crate) const EX_SPL_TOKEN_MAX_BATCH_ACCOUNTS: usize = 512;
/// Maximum number of ordered multisig signer occurrences.
pub(crate) const EX_SPL_TOKEN_MAX_MULTISIG_SIGNERS: usize = 11;
/// Maximum UI amount string length accepted before transaction assembly.
pub(crate) const EX_SPL_TOKEN_MAX_UI_AMOUNT_BYTES: usize = 255;
/// Canonical tracing target for this crate.
pub(crate) const TRACING_TARGET_EXECUTOR_SPL_TOKEN: &str = "kb-lib.executor.spl.token";

View File

@@ -0,0 +1,244 @@
// file: kb-lib/src/executor/spl/token/executor.rs
// version: 6
//! Exact classic SPL Token capability dispatch and typed plan construction.
/// Classic SPL Token executor implementation.
#[derive(Clone, Debug, Default)]
pub struct ExSplTokenExecutor;
impl crate::ExSplTokenExecutor {
fn exact_capability(
&self,
program_id: &crate::MdProgramId,
operation_code: &str,
) -> crate::ExApiExecutionCapability {
if program_id.0 != kb_program_ids::SPL_TOKEN_PROGRAM_ID {
return crate::ExApiExecutionCapability::unsupported(
"execution_spl_token_program_not_owned",
format!("program {} is not owned by kb_executor_spl_token", program_id.0),
);
}
if crate::EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES.contains(&operation_code) {
return crate::ExApiExecutionCapability::supported(operation_code);
}
if matches!(
operation_code,
"spl_token.initialize_mint_with_rent"
| "spl_token.initialize_account_with_rent"
| "spl_token.initialize_multisig_with_rent"
| "spl_token.initialize_account2"
) {
return crate::ExApiExecutionCapability::unsupported(
"execution_spl_token_historical_variant_decode_only",
format!(
"SPL Token operation {operation_code} is an obsolete historical initialization variant; use the current no-Rent operation"
),
);
}
return crate::ExApiExecutionCapability::unsupported(
"execution_spl_token_operation_unsupported",
format!("SPL Token operation {operation_code} is not implemented"),
);
}
}
impl crate::ExApiTypedInstructionExecutor for crate::ExSplTokenExecutor {
type Intent = crate::ExSplClassicTokenExecutionIntent;
fn capability(
&self,
program_id: &crate::MdProgramId,
operation_code: &str,
) -> crate::ExApiExecutionCapability {
return self.exact_capability(program_id, operation_code);
}
fn build_prepared_plan(
&self,
intent: &Self::Intent,
) -> kb_core::Result<crate::ExApiPreparedExecutionPlan> {
let program_id =
crate::MdProgramId(std::string::String::from(kb_program_ids::SPL_TOKEN_PROGRAM_ID));
return match self.exact_capability(&program_id, intent.operation.operation_code()) {
crate::ExApiExecutionCapability::Supported { operation_code: _ } => {
crate::executor_spl_token_build_prepared_plan(intent)
},
crate::ExApiExecutionCapability::Unsupported { reason_code, reason } => {
std::result::Result::Err(kb_core::Error::new(reason_code, reason))
},
};
}
}
impl crate::ExApiInstructionExecutor for crate::ExSplTokenExecutor {
fn executor_name(&self) -> &'static str {
return "kb_executor_spl_token";
}
fn executor_version(&self) -> &'static str {
return env!("CARGO_PKG_VERSION");
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::SPL_TOKEN_PROGRAM_ID];
}
fn supports_request(
&self,
request: &crate::ExApiExecutionRequest,
) -> crate::ExApiExecutionSupport {
return match self.exact_capability(&request.program_id, &request.operation_code) {
crate::ExApiExecutionCapability::Supported { operation_code: _ } => {
crate::ExApiExecutionSupport::Yes
},
crate::ExApiExecutionCapability::Unsupported { reason_code: _, reason: _ } => {
crate::ExApiExecutionSupport::No
},
};
}
fn build_plan(
&self,
request: &crate::ExApiExecutionRequest,
) -> kb_core::Result<crate::ExApiExecutionPlan> {
match self.exact_capability(&request.program_id, &request.operation_code) {
crate::ExApiExecutionCapability::Supported { operation_code: _ } => {},
crate::ExApiExecutionCapability::Unsupported { reason_code, reason } => {
return std::result::Result::Err(kb_core::Error::new(reason_code, reason));
},
}
let intent = match serde_json::from_str::<crate::ExSplClassicTokenExecutionIntent>(
&request.payload_json,
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token_intent_deserialize_failed",
error.to_string(),
));
},
};
if intent.operation.operation_code() != request.operation_code.as_str() {
return std::result::Result::Err(kb_core::Error::new(
"execution_operation_code_mismatch",
format!(
"request operation {} does not match typed intent operation {}",
request.operation_code,
intent.operation.operation_code()
),
));
}
let prepared =
match crate::ExApiTypedInstructionExecutor::build_prepared_plan(self, &intent) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let payload_value = match serde_json::to_value(&prepared) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token_plan_serialize_failed",
error.to_string(),
));
},
};
let payload_json = match crate::executor_api_serialize_payload_json(&payload_value) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
return std::result::Result::Ok(crate::ExApiExecutionPlan {
executor_name: std::string::String::from("kb_executor_spl_token"),
instruction_count: prepared.instructions.len(),
payload_json,
});
}
}
#[cfg(test)]
mod tests {
fn request(program_id: &str, operation_code: &str) -> crate::ExApiExecutionRequest {
return crate::ExApiExecutionRequest {
program_id: crate::MdProgramId(program_id.to_string()),
operation_code: operation_code.to_string(),
payload_json: std::string::String::from("{}"),
};
}
#[test]
fn exact_capabilities_cover_current_and_recent_operations_only() {
let executor = crate::ExSplTokenExecutor;
for operation_code in crate::EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES {
let request = request(kb_program_ids::SPL_TOKEN_PROGRAM_ID, operation_code);
assert_eq!(
crate::ExApiInstructionExecutor::supports_request(&executor, &request),
crate::ExApiExecutionSupport::Yes
);
}
for operation_code in [
"spl_token.initialize_mint_with_rent",
"spl_token.initialize_account_with_rent",
"spl_token.initialize_multisig_with_rent",
"spl_token.initialize_account2",
] {
let capability = crate::ExApiTypedInstructionExecutor::capability(
&executor,
&crate::MdProgramId(kb_program_ids::SPL_TOKEN_PROGRAM_ID.to_string()),
operation_code,
);
match capability {
crate::ExApiExecutionCapability::Unsupported { reason_code, reason: _ } => {
assert_eq!(reason_code, "execution_spl_token_historical_variant_decode_only");
},
crate::ExApiExecutionCapability::Supported { operation_code: _ } => {
panic!("historical variant must be decode-only");
},
}
}
}
#[test]
fn program_dispatch_is_exact() {
let executor = crate::ExSplTokenExecutor;
let foreign = request(
kb_program_ids::SPL_TOKEN2022_PROGRAM_ID,
crate::EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION,
);
assert_eq!(
crate::ExApiInstructionExecutor::supports_request(&executor, &foreign),
crate::ExApiExecutionSupport::No
);
}
#[test]
fn machine_readable_matrix_matches_executor_policy() {
let matrix = serde_json::from_str::<serde_json::Value>(include_str!(
"../../../../../docs/SPL_TOKEN_MATRIX.json"
))
.unwrap_or_else(|error| panic!("matrix parsing failed: {error}"));
let instructions = matrix["instructions"]
.as_array()
.unwrap_or_else(|| panic!("matrix instructions must be an array"));
let mut supported = 0_usize;
let mut operation_codes = std::vec::Vec::new();
for instruction in instructions {
let status = instruction["executorSupport"]["status"]
.as_str()
.unwrap_or_else(|| panic!("executorSupport.status missing"));
if status == "supported" {
supported += 1;
operation_codes.push(
instruction["executorSupport"]["operationCode"]
.as_str()
.unwrap_or_else(|| panic!("supported operationCode missing")),
);
}
}
assert_eq!(supported, crate::EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES.len());
assert_eq!(instructions.len() - supported, 4);
operation_codes.sort_unstable();
let mut compiled = crate::EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES.to_vec();
compiled.sort_unstable();
assert_eq!(operation_codes, compiled);
}
}

View File

@@ -0,0 +1,463 @@
// file: kb-lib/src/executor/spl/token/intent.rs
// version: 4
//! Typed classic SPL Token execution intents.
use ts_rs::TS; // rust-rules: derive-import
/// Stable operation code for mint initialization through `InitializeMint2`.
pub const EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION: &str = "spl_token.initialize_mint";
/// Stable operation code for token-account initialization through `InitializeAccount3`.
pub const EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION: &str = "spl_token.initialize_account";
/// Stable operation code for multisig initialization through `InitializeMultisig2`.
pub const EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION: &str = "spl_token.initialize_multisig";
/// Stable operation code for an unchecked token transfer.
pub const EX_SPL_TOKEN_TRANSFER_OPERATION: &str = "spl_token.transfer";
/// Stable operation code for an approval.
pub const EX_SPL_TOKEN_APPROVE_OPERATION: &str = "spl_token.approve";
/// Stable operation code for a delegate revocation.
pub const EX_SPL_TOKEN_REVOKE_OPERATION: &str = "spl_token.revoke";
/// Stable operation code for an authority change.
pub const EX_SPL_TOKEN_SET_AUTHORITY_OPERATION: &str = "spl_token.set_authority";
/// Stable operation code for minting tokens.
pub const EX_SPL_TOKEN_MINT_TO_OPERATION: &str = "spl_token.mint_to";
/// Stable operation code for burning tokens.
pub const EX_SPL_TOKEN_BURN_OPERATION: &str = "spl_token.burn";
/// Stable operation code for closing a token account.
pub const EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION: &str = "spl_token.close_account";
/// Stable operation code for freezing a token account.
pub const EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION: &str = "spl_token.freeze_account";
/// Stable operation code for thawing a token account.
pub const EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION: &str = "spl_token.thaw_account";
/// Stable operation code for a checked token transfer.
pub const EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION: &str = "spl_token.transfer_checked";
/// Stable operation code for a checked approval.
pub const EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION: &str = "spl_token.approve_checked";
/// Stable operation code for checked minting.
pub const EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION: &str = "spl_token.mint_to_checked";
/// Stable operation code for checked burning.
pub const EX_SPL_TOKEN_BURN_CHECKED_OPERATION: &str = "spl_token.burn_checked";
/// Stable operation code for synchronizing wrapped SOL.
pub const EX_SPL_TOKEN_SYNC_NATIVE_OPERATION: &str = "spl_token.sync_native";
/// Stable operation code for querying account data size.
pub const EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION: &str = "spl_token.get_account_data_size";
/// Stable operation code for the classic compatibility no-op.
pub const EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION: &str =
"spl_token.initialize_immutable_owner";
/// Stable operation code for raw-to-UI amount conversion.
pub const EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION: &str = "spl_token.amount_to_ui_amount";
/// Stable operation code for UI-to-raw amount conversion.
pub const EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION: &str = "spl_token.ui_amount_to_amount";
/// Stable operation code for rescuing excess lamports.
pub const EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION: &str =
"spl_token.withdraw_excess_lamports";
/// Stable operation code for the recent wrapped-SOL partial unwrap.
pub const EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION: &str = "spl_token.unwrap_lamports";
/// Stable operation code for a recent bounded batch.
pub const EX_SPL_TOKEN_BATCH_OPERATION: &str = "spl_token.batch";
/// Operation codes constructible by this executor.
pub const EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES: &[&str] = &[
EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION,
EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION,
EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION,
EX_SPL_TOKEN_TRANSFER_OPERATION,
EX_SPL_TOKEN_APPROVE_OPERATION,
EX_SPL_TOKEN_REVOKE_OPERATION,
EX_SPL_TOKEN_SET_AUTHORITY_OPERATION,
EX_SPL_TOKEN_MINT_TO_OPERATION,
EX_SPL_TOKEN_BURN_OPERATION,
EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION,
EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION,
EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION,
EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION,
EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION,
EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION,
EX_SPL_TOKEN_BURN_CHECKED_OPERATION,
EX_SPL_TOKEN_SYNC_NATIVE_OPERATION,
EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION,
EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION,
EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION,
EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION,
EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION,
EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION,
EX_SPL_TOKEN_BATCH_OPERATION,
];
/// Exact unsigned on-chain amount represented as a decimal JSON string.
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenAmount.ts"
)]
pub struct ExSplClassicTokenAmount(
/// Canonical unsigned decimal representation.
pub std::string::String,
);
/// Ordered simple or multisig authority supplied to an instruction builder.
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenAuthority.ts"
)]
pub struct ExSplClassicTokenAuthority {
/// Authority account. It signs only when `multisig_signers` is empty.
pub authority: crate::MdPubkey,
/// Ordered multisig signer occurrences. Duplicate metas remain ordered.
pub multisig_signers: std::vec::Vec<crate::MdPubkey>,
}
/// Authority domain used by `SetAuthority`.
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
#[serde(rename_all = "snake_case")]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenAuthorityType.ts"
)]
pub enum ExSplClassicTokenAuthorityType {
/// Mint authority.
MintTokens,
/// Freeze authority.
FreezeAccount,
/// Token-account owner.
AccountOwner,
/// Token-account close authority.
CloseAccount,
}
/// One officially constructible non-batch instruction.
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
#[serde(tag = "instruction", rename_all = "snake_case")]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenSingleOperation.ts"
)]
pub enum ExSplClassicTokenSingleOperation {
/// Initialize a mint with the current no-Rent builder.
InitializeMint {
/// Mint account already created for the classic Token program.
mint: crate::MdPubkey,
/// Mint authority.
mint_authority: crate::MdPubkey,
/// Optional freeze authority.
freeze_authority: std::option::Option<crate::MdPubkey>,
/// Mint decimals.
decimals: u8,
},
/// Initialize a token account with the current no-Rent builder.
InitializeAccount {
/// Token account already created for the classic Token program.
account: crate::MdPubkey,
/// Mint associated with the account.
mint: crate::MdPubkey,
/// Token-account owner.
owner: crate::MdPubkey,
},
/// Initialize a multisig with the current no-Rent builder.
InitializeMultisig {
/// Multisig account already created for the classic Token program.
multisig: crate::MdPubkey,
/// Ordered member accounts.
members: std::vec::Vec<crate::MdPubkey>,
/// Required member threshold.
threshold: u8,
},
/// Transfer a raw token amount without carrying the mint or decimals in the wire.
Transfer {
/// Source token account.
source: crate::MdPubkey,
/// Destination token account.
destination: crate::MdPubkey,
/// Owner, delegate or multisig authority.
authority: crate::ExSplClassicTokenAuthority,
/// Exact raw token amount.
amount: crate::ExSplClassicTokenAmount,
},
/// Approve a delegate for a raw token allowance.
Approve {
/// Source token account.
source: crate::MdPubkey,
/// Delegate account.
delegate: crate::MdPubkey,
/// Owner or multisig authority.
authority: crate::ExSplClassicTokenAuthority,
/// Exact raw allowance.
amount: crate::ExSplClassicTokenAmount,
},
/// Revoke the current delegate.
Revoke {
/// Source token account.
source: crate::MdPubkey,
/// Owner or multisig authority.
authority: crate::ExSplClassicTokenAuthority,
},
/// Change or revoke an authority.
SetAuthority {
/// Mint or token account whose authority changes.
owned: crate::MdPubkey,
/// Authority domain.
authority_type: crate::ExSplClassicTokenAuthorityType,
/// New authority, or `None` to revoke it.
new_authority: std::option::Option<crate::MdPubkey>,
/// Current simple or multisig authority.
current_authority: crate::ExSplClassicTokenAuthority,
},
/// Mint a raw token amount.
MintTo {
/// Mint account.
mint: crate::MdPubkey,
/// Destination token account.
destination: crate::MdPubkey,
/// Mint authority.
authority: crate::ExSplClassicTokenAuthority,
/// Exact raw amount.
amount: crate::ExSplClassicTokenAmount,
},
/// Burn a raw token amount.
Burn {
/// Source token account.
source: crate::MdPubkey,
/// Mint account.
mint: crate::MdPubkey,
/// Owner, delegate or multisig authority.
authority: crate::ExSplClassicTokenAuthority,
/// Exact raw amount.
amount: crate::ExSplClassicTokenAmount,
},
/// Close a token account.
CloseAccount {
/// Token account to close.
account: crate::MdPubkey,
/// Lamport destination.
destination: crate::MdPubkey,
/// Owner or close authority.
authority: crate::ExSplClassicTokenAuthority,
},
/// Freeze a token account.
FreezeAccount {
/// Token account to freeze.
account: crate::MdPubkey,
/// Mint account.
mint: crate::MdPubkey,
/// Freeze authority.
authority: crate::ExSplClassicTokenAuthority,
},
/// Thaw a token account.
ThawAccount {
/// Token account to thaw.
account: crate::MdPubkey,
/// Mint account.
mint: crate::MdPubkey,
/// Freeze authority.
authority: crate::ExSplClassicTokenAuthority,
},
/// Transfer while checking an explicit mint and decimals value.
TransferChecked {
/// Source token account.
source: crate::MdPubkey,
/// Mint account.
mint: crate::MdPubkey,
/// Destination token account.
destination: crate::MdPubkey,
/// Owner, delegate or multisig authority.
authority: crate::ExSplClassicTokenAuthority,
/// Exact raw amount.
amount: crate::ExSplClassicTokenAmount,
/// Expected mint decimals.
decimals: u8,
},
/// Approve a delegate while checking an explicit mint and decimals value.
ApproveChecked {
/// Source token account.
source: crate::MdPubkey,
/// Mint account.
mint: crate::MdPubkey,
/// Delegate account.
delegate: crate::MdPubkey,
/// Owner or multisig authority.
authority: crate::ExSplClassicTokenAuthority,
/// Exact raw allowance.
amount: crate::ExSplClassicTokenAmount,
/// Expected mint decimals.
decimals: u8,
},
/// Mint while checking explicit decimals.
MintToChecked {
/// Mint account.
mint: crate::MdPubkey,
/// Destination token account.
destination: crate::MdPubkey,
/// Mint authority.
authority: crate::ExSplClassicTokenAuthority,
/// Exact raw amount.
amount: crate::ExSplClassicTokenAmount,
/// Expected mint decimals.
decimals: u8,
},
/// Burn while checking explicit decimals.
BurnChecked {
/// Source token account.
source: crate::MdPubkey,
/// Mint account.
mint: crate::MdPubkey,
/// Owner, delegate or multisig authority.
authority: crate::ExSplClassicTokenAuthority,
/// Exact raw amount.
amount: crate::ExSplClassicTokenAmount,
/// Expected mint decimals.
decimals: u8,
},
/// Synchronize a wrapped-SOL account.
SyncNative {
/// Wrapped-SOL token account.
account: crate::MdPubkey,
/// Include the optional Rent sysvar account published by interface 3.0.0.
include_rent_sysvar: bool,
},
/// Query the token-account size for a mint.
GetAccountDataSize {
/// Mint account.
mint: crate::MdPubkey,
},
/// Build the classic-program immutable-owner compatibility no-op.
InitializeImmutableOwner {
/// Token account being prepared.
account: crate::MdPubkey,
},
/// Convert a raw amount using mint decimals through return data.
AmountToUiAmount {
/// Mint account.
mint: crate::MdPubkey,
/// Exact raw amount.
amount: crate::ExSplClassicTokenAmount,
},
/// Convert a UI amount using mint decimals through return data.
UiAmountToAmount {
/// Mint account.
mint: crate::MdPubkey,
/// Exact UTF-8 UI amount.
ui_amount: std::string::String,
},
/// Withdraw lamports above rent exemption.
WithdrawExcessLamports {
/// Program-owned source account.
account: crate::MdPubkey,
/// Lamport destination.
destination: crate::MdPubkey,
/// Owner or multisig authority.
authority: crate::ExSplClassicTokenAuthority,
},
/// Unwrap some or all lamports from a wrapped-SOL account.
UnwrapLamports {
/// Wrapped-SOL token account.
account: crate::MdPubkey,
/// Lamport destination.
destination: crate::MdPubkey,
/// Owner or multisig authority.
authority: crate::ExSplClassicTokenAuthority,
/// Exact lamports to unwrap, or `None` for the complete balance.
amount_lamports: std::option::Option<crate::ExSplClassicTokenAmount>,
},
}
impl crate::ExSplClassicTokenSingleOperation {
/// Returns the stable operation code.
pub fn operation_code(&self) -> &'static str {
return match self {
Self::InitializeMint { .. } => crate::EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION,
Self::InitializeAccount { .. } => crate::EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION,
Self::InitializeMultisig { .. } => crate::EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION,
Self::Transfer { .. } => crate::EX_SPL_TOKEN_TRANSFER_OPERATION,
Self::Approve { .. } => crate::EX_SPL_TOKEN_APPROVE_OPERATION,
Self::Revoke { .. } => crate::EX_SPL_TOKEN_REVOKE_OPERATION,
Self::SetAuthority { .. } => crate::EX_SPL_TOKEN_SET_AUTHORITY_OPERATION,
Self::MintTo { .. } => crate::EX_SPL_TOKEN_MINT_TO_OPERATION,
Self::Burn { .. } => crate::EX_SPL_TOKEN_BURN_OPERATION,
Self::CloseAccount { .. } => crate::EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION,
Self::FreezeAccount { .. } => crate::EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION,
Self::ThawAccount { .. } => crate::EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION,
Self::TransferChecked { .. } => crate::EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION,
Self::ApproveChecked { .. } => crate::EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION,
Self::MintToChecked { .. } => crate::EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION,
Self::BurnChecked { .. } => crate::EX_SPL_TOKEN_BURN_CHECKED_OPERATION,
Self::SyncNative { .. } => crate::EX_SPL_TOKEN_SYNC_NATIVE_OPERATION,
Self::GetAccountDataSize { .. } => crate::EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION,
Self::InitializeImmutableOwner { .. } => {
crate::EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION
},
Self::AmountToUiAmount { .. } => crate::EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION,
Self::UiAmountToAmount { .. } => crate::EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION,
Self::WithdrawExcessLamports { .. } => {
crate::EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION
},
Self::UnwrapLamports { .. } => crate::EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION,
};
}
pub(crate) fn requires_materialization(&self) -> bool {
return !matches!(
self,
Self::GetAccountDataSize { .. }
| Self::InitializeImmutableOwner { .. }
| Self::AmountToUiAmount { .. }
| Self::UiAmountToAmount { .. }
);
}
}
/// Top-level SPL Token operation, including the recent bounded Batch builder.
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
#[serde(tag = "operation", rename_all = "snake_case")]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenOperation.ts"
)]
pub enum ExSplClassicTokenOperation {
/// Build one non-batch instruction.
Instruction {
/// Exact instruction arguments.
value: crate::ExSplClassicTokenSingleOperation,
},
/// Build one Batch from ordered, non-batch child operations.
Batch {
/// Ordered child operations. Nested Batch is impossible in this contract.
instructions: std::vec::Vec<crate::ExSplClassicTokenSingleOperation>,
},
}
impl crate::ExSplClassicTokenOperation {
/// Returns the stable top-level operation code.
pub fn operation_code(&self) -> &'static str {
return match self {
Self::Instruction { value } => value.operation_code(),
Self::Batch { .. } => crate::EX_SPL_TOKEN_BATCH_OPERATION,
};
}
pub(crate) fn requires_materialization(&self) -> bool {
return match self {
Self::Instruction { value } => value.requires_materialization(),
Self::Batch { instructions } => {
instructions.iter().any(|value| return value.requires_materialization())
},
};
}
}
/// Complete typed intent accepted by the classic SPL Token executor.
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenExecutionIntent.ts"
)]
pub struct ExSplClassicTokenExecutionIntent {
/// Stable caller-provided identifier used for logs and replay correlation.
pub intent_id: std::string::String,
/// Transaction fee payer.
pub fee_payer: crate::MdPubkey,
/// Conservative execution policy. Its default is simulation-only.
pub policy: crate::ExApiExecutionPolicy,
/// Typed classic Token operation.
pub operation: crate::ExSplClassicTokenOperation,
}

View File

@@ -581,6 +581,56 @@ pub use self::executor::EX_SPL_MEMO_ADD_MEMO_OPERATION;
pub use self::executor::EX_SPL_MEMO_MAX_MESSAGE_BYTES; pub use self::executor::EX_SPL_MEMO_MAX_MESSAGE_BYTES;
/// Exposes the SPL Memo signer bound. /// Exposes the SPL Memo signer bound.
pub use self::executor::EX_SPL_MEMO_MAX_SIGNERS; pub use self::executor::EX_SPL_MEMO_MAX_SIGNERS;
/// Exposes `EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_AMOUNT_TO_UI_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_APPROVE_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_APPROVE_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_APPROVE_OPERATION;
/// Exposes `EX_SPL_TOKEN_BATCH_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_BATCH_OPERATION;
/// Exposes `EX_SPL_TOKEN_BURN_CHECKED_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_BURN_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_BURN_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_BURN_OPERATION;
/// Exposes `EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_CLOSE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_FREEZE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_GET_ACCOUNT_DATA_SIZE_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_INITIALIZE_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_INITIALIZE_IMMUTABLE_OWNER_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_INITIALIZE_MINT_OPERATION;
/// Exposes `EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_INITIALIZE_MULTISIG_OPERATION;
/// Exposes `EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_MINT_TO_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_MINT_TO_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_MINT_TO_OPERATION;
/// Exposes `EX_SPL_TOKEN_REVOKE_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_REVOKE_OPERATION;
/// Exposes `EX_SPL_TOKEN_SET_AUTHORITY_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_SET_AUTHORITY_OPERATION;
/// Exposes `EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES`.
pub use self::executor::EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES;
/// Exposes `EX_SPL_TOKEN_SYNC_NATIVE_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_SYNC_NATIVE_OPERATION;
/// Exposes `EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_THAW_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_TRANSFER_CHECKED_OPERATION;
/// Exposes `EX_SPL_TOKEN_TRANSFER_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_TRANSFER_OPERATION;
/// Exposes `EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_UI_AMOUNT_TO_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_UNWRAP_LAMPORTS_OPERATION;
/// Exposes `EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_WITHDRAW_EXCESS_LAMPORTS_OPERATION;
/// Exposes `EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION`. /// Exposes `EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION`.
pub use self::executor::EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION; pub use self::executor::EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION`. /// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION`.
@@ -1027,6 +1077,18 @@ pub use self::executor::ExSplAssociatedTokenAccountExecutor;
pub use self::executor::ExSplAssociatedTokenAccountOperation; pub use self::executor::ExSplAssociatedTokenAccountOperation;
/// Exposes the exact Token Program used by ATA derivation. /// Exposes the exact Token Program used by ATA derivation.
pub use self::executor::ExSplAssociatedTokenProgram; pub use self::executor::ExSplAssociatedTokenProgram;
/// Exposes `ExSplClassicTokenAmount`.
pub use self::executor::ExSplClassicTokenAmount;
/// Exposes `ExSplClassicTokenAuthority`.
pub use self::executor::ExSplClassicTokenAuthority;
/// Exposes `ExSplClassicTokenAuthorityType`.
pub use self::executor::ExSplClassicTokenAuthorityType;
/// Exposes `ExSplClassicTokenExecutionIntent`.
pub use self::executor::ExSplClassicTokenExecutionIntent;
/// Exposes `ExSplClassicTokenOperation`.
pub use self::executor::ExSplClassicTokenOperation;
/// Exposes `ExSplClassicTokenSingleOperation`.
pub use self::executor::ExSplClassicTokenSingleOperation;
/// Exposes the typed SPL ElGamal registry execution intent. /// Exposes the typed SPL ElGamal registry execution intent.
pub use self::executor::ExSplElgamalRegistryExecutionIntent; pub use self::executor::ExSplElgamalRegistryExecutionIntent;
/// Exposes the typed SPL ElGamal registry executor. /// Exposes the typed SPL ElGamal registry executor.
@@ -1694,6 +1756,14 @@ pub(crate) use self::decoder::decoder_spl_token2022_decode;
pub(crate) use self::decoder::decoder_spl_token2022_entry_for_tag; pub(crate) use self::decoder::decoder_spl_token2022_entry_for_tag;
/// Returns the first byte of one retained Token-2022 payload. /// Returns the first byte of one retained Token-2022 payload.
pub(crate) use self::decoder::decoder_spl_token2022_payload_tag; pub(crate) use self::decoder::decoder_spl_token2022_payload_tag;
/// Crate-root access to `EX_SPL_TOKEN_MAX_BATCH_ACCOUNTS`.
pub(crate) use self::executor::EX_SPL_TOKEN_MAX_BATCH_ACCOUNTS;
/// Crate-root access to `EX_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS`.
pub(crate) use self::executor::EX_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS;
/// Crate-root access to `EX_SPL_TOKEN_MAX_MULTISIG_SIGNERS`.
pub(crate) use self::executor::EX_SPL_TOKEN_MAX_MULTISIG_SIGNERS;
/// Crate-root access to `EX_SPL_TOKEN_MAX_UI_AMOUNT_BYTES`.
pub(crate) use self::executor::EX_SPL_TOKEN_MAX_UI_AMOUNT_BYTES;
/// Maximum ordered multisig signer occurrences for SPL Token-2022. /// Maximum ordered multisig signer occurrences for SPL Token-2022.
pub(crate) use self::executor::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS; pub(crate) use self::executor::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS;
/// Maximum transfer-fee source account count for SPL Token-2022. /// Maximum transfer-fee source account count for SPL Token-2022.
@@ -1708,6 +1778,8 @@ pub(crate) use self::executor::TRACING_TARGET_EXECUTOR_SPL_ATA;
pub(crate) use self::executor::TRACING_TARGET_EXECUTOR_SPL_ELGAMAL_REGISTRY; pub(crate) use self::executor::TRACING_TARGET_EXECUTOR_SPL_ELGAMAL_REGISTRY;
/// Canonical SPL Memo tracing target. /// Canonical SPL Memo tracing target.
pub(crate) use self::executor::TRACING_TARGET_EXECUTOR_SPL_MEMO; pub(crate) use self::executor::TRACING_TARGET_EXECUTOR_SPL_MEMO;
/// Crate-root access to `TRACING_TARGET_EXECUTOR_SPL_TOKEN`.
pub(crate) use self::executor::TRACING_TARGET_EXECUTOR_SPL_TOKEN;
/// Canonical SPL Token-2022 tracing target. /// Canonical SPL Token-2022 tracing target.
pub(crate) use self::executor::TRACING_TARGET_EXECUTOR_SPL_TOKEN2022; pub(crate) use self::executor::TRACING_TARGET_EXECUTOR_SPL_TOKEN2022;
/// Crate-root access to `build_prepared_plan` from `address_lookup_table`. /// Crate-root access to `build_prepared_plan` from `address_lookup_table`.
@@ -1752,6 +1824,8 @@ pub(crate) use self::executor::executor_spl_ata_build_prepared_plan;
pub(crate) use self::executor::executor_spl_elgamal_registry_build_prepared_plan; pub(crate) use self::executor::executor_spl_elgamal_registry_build_prepared_plan;
/// Internal SPL Memo plan builder. /// Internal SPL Memo plan builder.
pub(crate) use self::executor::executor_spl_memo_build_prepared_plan; pub(crate) use self::executor::executor_spl_memo_build_prepared_plan;
/// Crate-root access to `executor_spl_token_build_prepared_plan`.
pub(crate) use self::executor::executor_spl_token_build_prepared_plan;
/// Internal SPL Token-2022 prepared-plan builder. /// Internal SPL Token-2022 prepared-plan builder.
pub(crate) use self::executor::executor_spl_token2022_build_prepared_plan; pub(crate) use self::executor::executor_spl_token2022_build_prepared_plan;
/// Canonical processor name for the native and SPL administration materializer. /// Canonical processor name for the native and SPL administration materializer.

View File

@@ -774,7 +774,8 @@ mod tests {
.filter(|line| { .filter(|line| {
let trimmed = line.trim(); let trimmed = line.trim();
return trimmed.starts_with("pub(crate) const ") return trimmed.starts_with("pub(crate) const ")
&& trimmed.contains("TRACING_TARGET") && trimmed.contains("TRACING_")
&& trimmed.contains("TARGET")
&& trimmed.contains(": &str"); && trimmed.contains(": &str");
}) })
.count(); .count();

View File

@@ -97,10 +97,10 @@ def audit_kb_lib_tracing(root: pathlib.Path) -> list[Violation]:
re.MULTILINE, re.MULTILINE,
) )
for match in re_export_pattern.finditer(root_text): for match in re_export_pattern.finditer(root_text):
if match.group(1).endswith("_TRACING_TARGET"): if match.group(1).startswith("TRACING_TARGET_"):
re_exports.add(match.group(1)) re_exports.add(match.group(1))
target_pattern = re.compile( target_pattern = re.compile(
r'^pub\(crate\) const ([A-Z][A-Z0-9_]+_TRACING_TARGET): &str = "([^"]+)";$', r'^pub\(crate\) const (TRACING_TARGET_[A-Z0-9_]+): &str = "([^"]+)";$',
re.MULTILINE, re.MULTILINE,
) )
for constants in sorted((crate / "src").rglob("constants.rs")): for constants in sorted((crate / "src").rglob("constants.rs")):
@@ -121,7 +121,7 @@ def audit_kb_lib_tracing(root: pathlib.Path) -> list[Violation]:
) )
) )
macro_pattern = re.compile( macro_pattern = re.compile(
r"tracing::(?:debug|error|info|trace|warn)!\(\s*target:\s*crate::([A-Z][A-Z0-9_]+_TRACING_TARGET)" r"tracing::(?:debug|error|info|trace|warn)!\(\s*target:\s*crate::(TRACING_TARGET_[A-Z0-9_]+)"
) )
for path in sorted((crate / "src").rglob("*.rs")): for path in sorted((crate / "src").rglob("*.rs")):
relative = path.relative_to(root).as_posix() relative = path.relative_to(root).as_posix()
@@ -195,6 +195,8 @@ def audit_kb_lib_symbol_prefixes(root: pathlib.Path) -> list[Violation]:
kind = match.group(1) kind = match.group(1)
name = match.group(2) name = match.group(2)
expected = prefixes[0] if kind in {"const", "static"} else prefixes[2] if kind == "fn" else prefixes[1] expected = prefixes[0] if kind in {"const", "static"} else prefixes[2] if kind == "fn" else prefixes[1]
if kind in {"const", "static"} and name.startswith("TRACING_TARGET_"):
continue
if not name.startswith(expected): if not name.startswith(expected):
violations.append( violations.append(
Violation( Violation(
@@ -438,13 +440,13 @@ def audit_reserved_executor_scaffolds(root: pathlib.Path) -> list[Violation]:
"reserved executor must build only an explicit zero-instruction plan", "reserved executor must build only an explicit zero-instruction plan",
) )
) )
if reserved_count != 99: if reserved_count != 98:
violations.append( violations.append(
Violation( Violation(
"KH_EX007", "KH_EX007",
"kb-lib/src/executor", "kb-lib/src/executor",
1, 1,
f"expected 99 reserved executor boundaries, found {reserved_count}", f"expected 98 reserved executor boundaries, found {reserved_count}",
) )
) )
return violations return violations