From f965fcc58a6cfc7a15ce9706ec645be34f1a888e Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Fri, 24 Jul 2026 19:34:54 +0200 Subject: [PATCH] v0.1.0-pre.018 --- config/example.config.json | 120 +- kb-lib/Cargo.toml | 9 +- kb-lib/src/executor.rs | 257 +- kb-lib/src/executor/spl.rs | 253 +- kb-lib/src/executor/spl/token2022.rs | 302 +- kb-lib/src/executor/spl/token2022/builder.rs | 4935 +++++++++++++++++ .../executor/spl/token2022/confidential.rs | 601 ++ .../src/executor/spl/token2022/constants.rs | 13 + kb-lib/src/executor/spl/token2022/executor.rs | 333 ++ kb-lib/src/executor/spl/token2022/intent.rs | 1629 ++++++ kb-lib/src/lib.rs | 252 +- kb-lib/src/model/nomenclature.rs | 12 +- kb-lib/src/model/solana.rs | 7 +- scripts/audit_khadhroony_workspace_rules.py | 4 +- 14 files changed, 8604 insertions(+), 123 deletions(-) create mode 100644 kb-lib/src/executor/spl/token2022/builder.rs create mode 100644 kb-lib/src/executor/spl/token2022/confidential.rs create mode 100644 kb-lib/src/executor/spl/token2022/constants.rs create mode 100644 kb-lib/src/executor/spl/token2022/executor.rs create mode 100644 kb-lib/src/executor/spl/token2022/intent.rs diff --git a/config/example.config.json b/config/example.config.json index 54c1db3..9f8e06d 100644 --- a/config/example.config.json +++ b/config/example.config.json @@ -34,13 +34,13 @@ "kb_executor_metadata_spl_name_service", "kb_executor_solana_core", "kb_executor_spl_account_compression", - "kb_executor_spl_associated_token_account", + "kb-lib.executor.spl.associated_token_account", "kb_executor_spl_elgamal_registry", "kb_executor_spl_memo", "kb_executor_spl_noop", "kb_executor_spl_single_pool", "kb_executor_spl_token", - "kb_executor_spl_token2022", + "kb-lib.executor.spl.token2022", "kb-logging", "kb-lib.materializer.admin", "kb-lib.materializer.compliance", @@ -498,42 +498,42 @@ ] }, { - "name": "file_kb_executor_spl_associated_token_account_debug", + "name": "file_kb_lib_executor_spl_associated_token_account_debug", "enabled": true, "sink": "file", "level": "debug", - "path": "logs/devnet/kb_executor_spl_associated_token_account/debug.log", + "path": "logs/devnet/kb_lib_executor_spl_associated_token_account/debug.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_associated_token_account" + "kb-lib.executor.spl.associated_token_account" ] }, { - "name": "file_kb_executor_spl_associated_token_account_info", + "name": "file_kb_lib_executor_spl_associated_token_account_info", "enabled": true, "sink": "file", "level": "info", - "path": "logs/devnet/kb_executor_spl_associated_token_account/info.log", + "path": "logs/devnet/kb_lib_executor_spl_associated_token_account/info.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_associated_token_account" + "kb-lib.executor.spl.associated_token_account" ] }, { - "name": "file_kb_executor_spl_associated_token_account_error", + "name": "file_kb_lib_executor_spl_associated_token_account_error", "enabled": true, "sink": "file", "level": "error", - "path": "logs/devnet/kb_executor_spl_associated_token_account/error.jsonl", + "path": "logs/devnet/kb_lib_executor_spl_associated_token_account/error.jsonl", "rotation": "daily", "format": "json", "ansi": false, "targets": [ - "kb_executor_spl_associated_token_account" + "kb-lib.executor.spl.associated_token_account" ] }, { @@ -1317,42 +1317,42 @@ ] }, { - "name": "file_kb_executor_spl_token2022_debug", + "name": "file_kb_lib_executor_spl_token2022_debug", "enabled": true, "sink": "file", "level": "debug", - "path": "logs/devnet/kb_executor_spl_token2022/debug.log", + "path": "logs/devnet/kb_lib_executor_spl_token2022/debug.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_token2022" + "kb-lib.executor.spl.token2022" ] }, { - "name": "file_kb_executor_spl_token2022_info", + "name": "file_kb_lib_executor_spl_token2022_info", "enabled": true, "sink": "file", "level": "info", - "path": "logs/devnet/kb_executor_spl_token2022/info.log", + "path": "logs/devnet/kb_lib_executor_spl_token2022/info.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_token2022" + "kb-lib.executor.spl.token2022" ] }, { - "name": "file_kb_executor_spl_token2022_error", + "name": "file_kb_lib_executor_spl_token2022_error", "enabled": true, "sink": "file", "level": "error", - "path": "logs/devnet/kb_executor_spl_token2022/error.jsonl", + "path": "logs/devnet/kb_lib_executor_spl_token2022/error.jsonl", "rotation": "daily", "format": "json", "ansi": false, "targets": [ - "kb_executor_spl_token2022" + "kb-lib.executor.spl.token2022" ] } ], @@ -1636,13 +1636,13 @@ "kb_executor_metadata_spl_name_service", "kb_executor_solana_core", "kb_executor_spl_account_compression", - "kb_executor_spl_associated_token_account", + "kb-lib.executor.spl.associated_token_account", "kb_executor_spl_elgamal_registry", "kb_executor_spl_memo", "kb_executor_spl_noop", "kb_executor_spl_single_pool", "kb_executor_spl_token", - "kb_executor_spl_token2022", + "kb-lib.executor.spl.token2022", "kb-logging", "kb-lib.materializer.admin", "kb-lib.materializer.compliance", @@ -2100,42 +2100,42 @@ ] }, { - "name": "file_kb_executor_spl_associated_token_account_debug", + "name": "file_kb_lib_executor_spl_associated_token_account_debug", "enabled": true, "sink": "file", "level": "debug", - "path": "logs/mainnet_research/kb_executor_spl_associated_token_account/debug.log", + "path": "logs/mainnet_research/kb_lib_executor_spl_associated_token_account/debug.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_associated_token_account" + "kb-lib.executor.spl.associated_token_account" ] }, { - "name": "file_kb_executor_spl_associated_token_account_info", + "name": "file_kb_lib_executor_spl_associated_token_account_info", "enabled": true, "sink": "file", "level": "info", - "path": "logs/mainnet_research/kb_executor_spl_associated_token_account/info.log", + "path": "logs/mainnet_research/kb_lib_executor_spl_associated_token_account/info.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_associated_token_account" + "kb-lib.executor.spl.associated_token_account" ] }, { - "name": "file_kb_executor_spl_associated_token_account_error", + "name": "file_kb_lib_executor_spl_associated_token_account_error", "enabled": true, "sink": "file", "level": "error", - "path": "logs/mainnet_research/kb_executor_spl_associated_token_account/error.jsonl", + "path": "logs/mainnet_research/kb_lib_executor_spl_associated_token_account/error.jsonl", "rotation": "daily", "format": "json", "ansi": false, "targets": [ - "kb_executor_spl_associated_token_account" + "kb-lib.executor.spl.associated_token_account" ] }, { @@ -2919,42 +2919,42 @@ ] }, { - "name": "file_kb_executor_spl_token2022_debug", + "name": "file_kb_lib_executor_spl_token2022_debug", "enabled": true, "sink": "file", "level": "debug", - "path": "logs/mainnet_research/kb_executor_spl_token2022/debug.log", + "path": "logs/mainnet_research/kb_lib_executor_spl_token2022/debug.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_token2022" + "kb-lib.executor.spl.token2022" ] }, { - "name": "file_kb_executor_spl_token2022_info", + "name": "file_kb_lib_executor_spl_token2022_info", "enabled": true, "sink": "file", "level": "info", - "path": "logs/mainnet_research/kb_executor_spl_token2022/info.log", + "path": "logs/mainnet_research/kb_lib_executor_spl_token2022/info.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_token2022" + "kb-lib.executor.spl.token2022" ] }, { - "name": "file_kb_executor_spl_token2022_error", + "name": "file_kb_lib_executor_spl_token2022_error", "enabled": true, "sink": "file", "level": "error", - "path": "logs/mainnet_research/kb_executor_spl_token2022/error.jsonl", + "path": "logs/mainnet_research/kb_lib_executor_spl_token2022/error.jsonl", "rotation": "daily", "format": "json", "ansi": false, "targets": [ - "kb_executor_spl_token2022" + "kb-lib.executor.spl.token2022" ] } ], @@ -3438,13 +3438,13 @@ "kb_executor_metadata_spl_name_service", "kb_executor_solana_core", "kb_executor_spl_account_compression", - "kb_executor_spl_associated_token_account", + "kb-lib.executor.spl.associated_token_account", "kb_executor_spl_elgamal_registry", "kb_executor_spl_memo", "kb_executor_spl_noop", "kb_executor_spl_single_pool", "kb_executor_spl_token", - "kb_executor_spl_token2022", + "kb-lib.executor.spl.token2022", "kb-logging", "kb-lib.materializer.admin", "kb-lib.materializer.compliance", @@ -3902,42 +3902,42 @@ ] }, { - "name": "file_kb_executor_spl_associated_token_account_debug", + "name": "file_kb_lib_executor_spl_associated_token_account_debug", "enabled": true, "sink": "file", "level": "debug", - "path": "logs/mainnet/kb_executor_spl_associated_token_account/debug.log", + "path": "logs/mainnet/kb_lib_executor_spl_associated_token_account/debug.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_associated_token_account" + "kb-lib.executor.spl.associated_token_account" ] }, { - "name": "file_kb_executor_spl_associated_token_account_info", + "name": "file_kb_lib_executor_spl_associated_token_account_info", "enabled": true, "sink": "file", "level": "info", - "path": "logs/mainnet/kb_executor_spl_associated_token_account/info.log", + "path": "logs/mainnet/kb_lib_executor_spl_associated_token_account/info.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_associated_token_account" + "kb-lib.executor.spl.associated_token_account" ] }, { - "name": "file_kb_executor_spl_associated_token_account_error", + "name": "file_kb_lib_executor_spl_associated_token_account_error", "enabled": true, "sink": "file", "level": "error", - "path": "logs/mainnet/kb_executor_spl_associated_token_account/error.jsonl", + "path": "logs/mainnet/kb_lib_executor_spl_associated_token_account/error.jsonl", "rotation": "daily", "format": "json", "ansi": false, "targets": [ - "kb_executor_spl_associated_token_account" + "kb-lib.executor.spl.associated_token_account" ] }, { @@ -4721,42 +4721,42 @@ ] }, { - "name": "file_kb_executor_spl_token2022_debug", + "name": "file_kb_lib_executor_spl_token2022_debug", "enabled": true, "sink": "file", "level": "debug", - "path": "logs/mainnet/kb_executor_spl_token2022/debug.log", + "path": "logs/mainnet/kb_lib_executor_spl_token2022/debug.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_token2022" + "kb-lib.executor.spl.token2022" ] }, { - "name": "file_kb_executor_spl_token2022_info", + "name": "file_kb_lib_executor_spl_token2022_info", "enabled": true, "sink": "file", "level": "info", - "path": "logs/mainnet/kb_executor_spl_token2022/info.log", + "path": "logs/mainnet/kb_lib_executor_spl_token2022/info.log", "rotation": "daily", "format": "human", "ansi": false, "targets": [ - "kb_executor_spl_token2022" + "kb-lib.executor.spl.token2022" ] }, { - "name": "file_kb_executor_spl_token2022_error", + "name": "file_kb_lib_executor_spl_token2022_error", "enabled": true, "sink": "file", "level": "error", - "path": "logs/mainnet/kb_executor_spl_token2022/error.jsonl", + "path": "logs/mainnet/kb_lib_executor_spl_token2022/error.jsonl", "rotation": "daily", "format": "json", "ansi": false, "targets": [ - "kb_executor_spl_token2022" + "kb-lib.executor.spl.token2022" ] } ], diff --git a/kb-lib/Cargo.toml b/kb-lib/Cargo.toml index 3cdb438..cb887e2 100644 --- a/kb-lib/Cargo.toml +++ b/kb-lib/Cargo.toml @@ -1,5 +1,5 @@ # file: kb-lib/Cargo.toml -# version: 10 +# version: 11 [package] name = "kb-lib" @@ -9,6 +9,7 @@ license.workspace = true publish.workspace = true [dependencies] +bytemuck.workspace = true base64.workspace = true borsh.workspace = true borsh_0_10.workspace = true @@ -31,7 +32,12 @@ solana-stake-interface.workspace = true solana-system-interface.workspace = true solana-vote-interface.workspace = true solana-zk-elgamal-proof-interface.workspace = true +solana-zk-sdk-pod.workspace = true spl-associated-token-account-interface.workspace = true +spl-token-group-interface.workspace = true +spl-token-metadata-interface.workspace = true +spl-token-2022-interface.workspace = true +spl-token-confidential-transfer-proof-extraction.workspace = true spl-memo-interface.workspace = true tracing.workspace = true ts-rs.workspace = true @@ -42,7 +48,6 @@ solana-ed25519-program.workspace = true solana-secp256k1-program.workspace = true solana-secp256r1-program.workspace = true spl-elgamal-registry-interface.workspace = true -spl-token-2022-interface.workspace = true spl-token-interface.workspace = true [lints] diff --git a/kb-lib/src/executor.rs b/kb-lib/src/executor.rs index bedf74d..111a381 100644 --- a/kb-lib/src/executor.rs +++ b/kb-lib/src/executor.rs @@ -1,5 +1,5 @@ // file: kb-lib/src/executor.rs -// version: 5 +// version: 6 //! Consolidated executor modules. @@ -507,6 +507,206 @@ pub use self::spl::EX_SPL_MEMO_ADD_MEMO_OPERATION; pub use self::spl::EX_SPL_MEMO_MAX_MESSAGE_BYTES; /// Exposes the SPL Memo signer bound. pub use self::spl::EX_SPL_MEMO_MAX_SIGNERS; +/// Exposes `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`. +pub use self::spl::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_APPROVE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BATCH_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_BATCH_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BURN_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG`. +pub use self::spl::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES`. +pub use self::spl::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES`. +pub use self::spl::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG`. +pub use self::spl::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG; +/// Exposes `EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES`. +pub use self::spl::EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES; +/// Exposes `EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES`. +pub use self::spl::EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES; +/// Exposes `EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES`. +pub use self::spl::EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES; +/// Exposes `EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES`. +pub use self::spl::EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES; +/// Exposes `EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_MINT_TO_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_MINT_TO_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PAUSE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_PAUSE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REALLOCATE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_REALLOCATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_RESUME_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_RESUME_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REVOKE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_REVOKE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES`. +pub use self::spl::EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES; +/// Exposes `EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_TRANSFER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION`. +pub use self::spl::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION; /// Exposes the reserved `spl/account_compression` executor. pub use self::spl::ExSplAccountCompressionExecutor; /// Exposes the typed SPL ATA execution intent. @@ -535,10 +735,48 @@ pub use self::spl::ExSplNoopExecutor; pub use self::spl::ExSplSinglePoolExecutor; /// Exposes the reserved `spl/stake_pool` executor. pub use self::spl::ExSplStakePoolExecutor; -/// Exposes the reserved `spl/token2022` executor. +/// Exposes `ExSplToken2022ExecutionIntent`. +pub use self::spl::ExSplToken2022ExecutionIntent; +/// Exposes `ExSplToken2022Executor`. pub use self::spl::ExSplToken2022Executor; +/// Exposes `ExSplToken2022Operation`. +pub use self::spl::ExSplToken2022Operation; +/// Exposes `ExSplTokenAmount`. +pub use self::spl::ExSplTokenAmount; +/// Exposes `ExSplTokenAuthority`. +pub use self::spl::ExSplTokenAuthority; +/// Exposes `ExSplTokenAuthorityType`. +pub use self::spl::ExSplTokenAuthorityType; +/// Exposes `ExSplTokenConfidentialExecutorSupport`. +pub use self::spl::ExSplTokenConfidentialExecutorSupport; +/// Exposes `ExSplTokenConfidentialMintBurnOperation`. +pub use self::spl::ExSplTokenConfidentialMintBurnOperation; +/// Exposes `ExSplTokenConfidentialOperation`. +pub use self::spl::ExSplTokenConfidentialOperation; +/// Exposes `ExSplTokenConfidentialProofKind`. +pub use self::spl::ExSplTokenConfidentialProofKind; +/// Exposes `ExSplTokenConfidentialProofLocation`. +pub use self::spl::ExSplTokenConfidentialProofLocation; +/// Exposes `ExSplTokenConfidentialProofReference`. +pub use self::spl::ExSplTokenConfidentialProofReference; +/// Exposes `ExSplTokenDecryptableBalance`. +pub use self::spl::ExSplTokenDecryptableBalance; +/// Exposes `ExSplTokenDefaultAccountState`. +pub use self::spl::ExSplTokenDefaultAccountState; +/// Exposes `ExSplTokenElGamalCiphertext`. +pub use self::spl::ExSplTokenElGamalCiphertext; +/// Exposes `ExSplTokenElGamalPubkey`. +pub use self::spl::ExSplTokenElGamalPubkey; /// Exposes the reserved `spl/token` executor. pub use self::spl::ExSplTokenExecutor; +/// Exposes `ExSplTokenMetadataField`. +pub use self::spl::ExSplTokenMetadataField; +/// Exposes `ExSplTokenMultiplier`. +pub use self::spl::ExSplTokenMultiplier; +/// Exposes `ExSplTokenSingleOperation`. +pub use self::spl::ExSplTokenSingleOperation; +/// Exposes `executor_spl_token2022_validate_confidential_proof_references`. +pub use self::spl::executor_spl_token2022_validate_confidential_proof_references; /// Exposes the reserved `stable/swap_hylo_exchange` executor. pub use self::stable::ExStableSwapHyloExchangeExecutor; /// Exposes the reserved `stable/swap_jupiter_stable` executor. @@ -616,16 +854,26 @@ pub(crate) use self::solana::executor_solana_core_zk_elgamal_build_prepared_plan pub(crate) use self::spl::EX_SPL_ATA_TRACING_TARGET; /// Canonical SPL Memo tracing target. pub(crate) use self::spl::EX_SPL_MEMO_TRACING_TARGET; +/// Maximum ordered multisig signer occurrences for SPL Token-2022. +pub(crate) use self::spl::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS; +/// Maximum transfer-fee source account count for SPL Token-2022. +pub(crate) use self::spl::EX_SPL_TOKEN2022_MAX_TRANSFER_FEE_SOURCE_ACCOUNTS; +/// Maximum UI amount byte length for SPL Token-2022. +pub(crate) use self::spl::EX_SPL_TOKEN2022_MAX_UI_AMOUNT_BYTES; +/// Canonical SPL Token-2022 tracing target. +pub(crate) use self::spl::EX_SPL_TOKEN2022_TRACING_TARGET; /// Internal SPL ATA plan builder. pub(crate) use self::spl::executor_spl_ata_build_prepared_plan; /// Internal SPL Memo plan builder. pub(crate) use self::spl::executor_spl_memo_build_prepared_plan; +/// Internal SPL Token-2022 prepared-plan builder. +pub(crate) use self::spl::executor_spl_token2022_build_prepared_plan; #[cfg(test)] mod reserved_executor_tests { #[test] fn every_reserved_executor_is_registered_and_builds_only_an_empty_plan() { - let executors: [&dyn crate::ExApiInstructionExecutor; 101] = [ + let executors: [&dyn crate::ExApiInstructionExecutor; 100] = [ &crate::ExAdapterSaberDecimalWrapperExecutor, &crate::ExAdminJupiterLockExecutor, &crate::ExAdminPumpFeesExecutor, @@ -709,7 +957,6 @@ mod reserved_executor_tests { &crate::ExSplSinglePoolExecutor, &crate::ExSplStakePoolExecutor, &crate::ExSplTokenExecutor, - &crate::ExSplToken2022Executor, &crate::ExStableSwapHyloExchangeExecutor, &crate::ExStableSwapJupiterStableExecutor, &crate::ExStableSwapNumeraireExecutor, @@ -728,7 +975,7 @@ mod reserved_executor_tests { &crate::ExWalletJupiterApeproSmartWalletExecutor, &crate::ExWeightedSwapStabbleExecutor, ]; - assert_eq!(executors.len(), 101); + assert_eq!(executors.len(), 100); for executor in executors { assert!(!executor.program_ids().is_empty()); for program_id in executor.program_ids() { diff --git a/kb-lib/src/executor/spl.rs b/kb-lib/src/executor/spl.rs index a404c9a..9e98c3c 100644 --- a/kb-lib/src/executor/spl.rs +++ b/kb-lib/src/executor/spl.rs @@ -1,5 +1,5 @@ // file: kb-lib/src/executor/spl.rs -// version: 4 +// version: 5 //! `spl` executor family. @@ -12,6 +12,7 @@ mod single_pool; mod stake_pool; mod token; mod token2022; + /// Exposes the reserved `spl/account_compression` executor. pub use self::account_compression::ExSplAccountCompressionExecutor; /// Exposes the idempotent ATA creation operation code. @@ -56,8 +57,246 @@ pub use self::single_pool::ExSplSinglePoolExecutor; pub use self::stake_pool::ExSplStakePoolExecutor; /// Exposes the reserved `spl/token` executor. pub use self::token::ExSplTokenExecutor; -/// Exposes the reserved `spl/token2022` executor. +/// Exposes `EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_APPROVE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BATCH_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_BATCH_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BURN_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG`. +pub use self::token2022::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES`. +pub use self::token2022::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES`. +pub use self::token2022::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG`. +pub use self::token2022::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG; +/// Exposes `EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES`. +pub use self::token2022::EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES; +/// Exposes `EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES`. +pub use self::token2022::EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES; +/// Exposes `EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES`. +pub use self::token2022::EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES; +/// Exposes `EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES`. +pub use self::token2022::EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES; +/// Exposes `EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_MINT_TO_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_MINT_TO_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PAUSE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_PAUSE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REALLOCATE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_REALLOCATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_RESUME_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_RESUME_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REVOKE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_REVOKE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES`. +pub use self::token2022::EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES; +/// Exposes `EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_TRANSFER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION`. +pub use self::token2022::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION; +/// Exposes `ExSplToken2022ExecutionIntent`. +pub use self::token2022::ExSplToken2022ExecutionIntent; +/// Exposes `ExSplToken2022Executor`. pub use self::token2022::ExSplToken2022Executor; +/// Exposes `ExSplToken2022Operation`. +pub use self::token2022::ExSplToken2022Operation; +/// Exposes `ExSplTokenAmount`. +pub use self::token2022::ExSplTokenAmount; +/// Exposes `ExSplTokenAuthority`. +pub use self::token2022::ExSplTokenAuthority; +/// Exposes `ExSplTokenAuthorityType`. +pub use self::token2022::ExSplTokenAuthorityType; +/// Exposes `ExSplTokenConfidentialExecutorSupport`. +pub use self::token2022::ExSplTokenConfidentialExecutorSupport; +/// Exposes `ExSplTokenConfidentialMintBurnOperation`. +pub use self::token2022::ExSplTokenConfidentialMintBurnOperation; +/// Exposes `ExSplTokenConfidentialOperation`. +pub use self::token2022::ExSplTokenConfidentialOperation; +/// Exposes `ExSplTokenConfidentialProofKind`. +pub use self::token2022::ExSplTokenConfidentialProofKind; +/// Exposes `ExSplTokenConfidentialProofLocation`. +pub use self::token2022::ExSplTokenConfidentialProofLocation; +/// Exposes `ExSplTokenConfidentialProofReference`. +pub use self::token2022::ExSplTokenConfidentialProofReference; +/// Exposes `ExSplTokenDecryptableBalance`. +pub use self::token2022::ExSplTokenDecryptableBalance; +/// Exposes `ExSplTokenDefaultAccountState`. +pub use self::token2022::ExSplTokenDefaultAccountState; +/// Exposes `ExSplTokenElGamalCiphertext`. +pub use self::token2022::ExSplTokenElGamalCiphertext; +/// Exposes `ExSplTokenElGamalPubkey`. +pub use self::token2022::ExSplTokenElGamalPubkey; +/// Exposes `ExSplTokenMetadataField`. +pub use self::token2022::ExSplTokenMetadataField; +/// Exposes `ExSplTokenMultiplier`. +pub use self::token2022::ExSplTokenMultiplier; +/// Exposes `ExSplTokenSingleOperation`. +pub use self::token2022::ExSplTokenSingleOperation; +/// Exposes `executor_spl_token2022_validate_confidential_proof_references`. +pub use self::token2022::executor_spl_token2022_validate_confidential_proof_references; /// Canonical SPL ATA tracing target. pub(crate) use self::associated_token_account::EX_SPL_ATA_TRACING_TARGET; @@ -67,3 +306,13 @@ pub(crate) use self::associated_token_account::executor_spl_ata_build_prepared_p pub(crate) use self::memo::EX_SPL_MEMO_TRACING_TARGET; /// Internal SPL Memo plan builder. pub(crate) use self::memo::executor_spl_memo_build_prepared_plan; +/// Maximum ordered multisig signer occurrences for SPL Token-2022. +pub(crate) use self::token2022::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS; +/// Maximum transfer-fee source account count for SPL Token-2022. +pub(crate) use self::token2022::EX_SPL_TOKEN2022_MAX_TRANSFER_FEE_SOURCE_ACCOUNTS; +/// Maximum UI amount byte length for SPL Token-2022. +pub(crate) use self::token2022::EX_SPL_TOKEN2022_MAX_UI_AMOUNT_BYTES; +/// Canonical SPL Token-2022 tracing target. +pub(crate) use self::token2022::EX_SPL_TOKEN2022_TRACING_TARGET; +/// Internal SPL Token-2022 prepared-plan builder. +pub(crate) use self::token2022::executor_spl_token2022_build_prepared_plan; diff --git a/kb-lib/src/executor/spl/token2022.rs b/kb-lib/src/executor/spl/token2022.rs index a3b076b..27cb0ae 100644 --- a/kb-lib/src/executor/spl/token2022.rs +++ b/kb-lib/src/executor/spl/token2022.rs @@ -1,49 +1,261 @@ // file: kb-lib/src/executor/spl/token2022.rs -// version: 2 +// version: 3 -//! Reserved executor for `spl_token2022`. +//! SPL Token-2022 executor. -/// Reserved executor for the `spl_token2022` program surface. -#[derive(Clone, Debug, Default)] -pub struct ExSplToken2022Executor; +mod builder; +mod confidential; +mod constants; +mod executor; +mod intent; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG`. +pub use self::confidential::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES`. +pub use self::confidential::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES`. +pub use self::confidential::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG`. +pub use self::confidential::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG; +/// Exposes `EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES`. +pub use self::confidential::EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES; +/// Exposes `EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES`. +pub use self::confidential::EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES; +/// Exposes `EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES`. +pub use self::confidential::EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES; +/// Exposes `EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES`. +pub use self::confidential::EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES; +/// Exposes `ExSplTokenConfidentialExecutorSupport`. +pub use self::confidential::ExSplTokenConfidentialExecutorSupport; +/// Exposes `ExSplTokenConfidentialMintBurnOperation`. +pub use self::confidential::ExSplTokenConfidentialMintBurnOperation; +/// Exposes `ExSplTokenConfidentialOperation`. +pub use self::confidential::ExSplTokenConfidentialOperation; +/// Exposes `ExSplTokenConfidentialProofKind`. +pub use self::confidential::ExSplTokenConfidentialProofKind; +/// Exposes `ExSplTokenConfidentialProofLocation`. +pub use self::confidential::ExSplTokenConfidentialProofLocation; +/// Exposes `ExSplTokenConfidentialProofReference`. +pub use self::confidential::ExSplTokenConfidentialProofReference; +/// Exposes `ExSplTokenDecryptableBalance`. +pub use self::confidential::ExSplTokenDecryptableBalance; +/// Exposes `ExSplTokenElGamalCiphertext`. +pub use self::confidential::ExSplTokenElGamalCiphertext; +/// Exposes `ExSplTokenElGamalPubkey`. +pub use self::confidential::ExSplTokenElGamalPubkey; +/// Exposes `executor_spl_token2022_validate_confidential_proof_references`. +pub use self::confidential::executor_spl_token2022_validate_confidential_proof_references; +/// Exposes `ExSplToken2022Executor`. +pub use self::executor::ExSplToken2022Executor; +/// Exposes `EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_APPROVE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BATCH_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_BATCH_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BURN_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_MINT_TO_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_MINT_TO_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PAUSE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_PAUSE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REALLOCATE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_REALLOCATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_RESUME_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_RESUME_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REVOKE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_REVOKE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES`. +pub use self::intent::EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES; +/// Exposes `EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_TRANSFER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION`. +pub use self::intent::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION; +/// Exposes `ExSplToken2022ExecutionIntent`. +pub use self::intent::ExSplToken2022ExecutionIntent; +/// Exposes `ExSplToken2022Operation`. +pub use self::intent::ExSplToken2022Operation; +/// Exposes `ExSplTokenAmount`. +pub use self::intent::ExSplTokenAmount; +/// Exposes `ExSplTokenAuthority`. +pub use self::intent::ExSplTokenAuthority; +/// Exposes `ExSplTokenAuthorityType`. +pub use self::intent::ExSplTokenAuthorityType; +/// Exposes `ExSplTokenDefaultAccountState`. +pub use self::intent::ExSplTokenDefaultAccountState; +/// Exposes `ExSplTokenMetadataField`. +pub use self::intent::ExSplTokenMetadataField; +/// Exposes `ExSplTokenMultiplier`. +pub use self::intent::ExSplTokenMultiplier; +/// Exposes `ExSplTokenSingleOperation`. +pub use self::intent::ExSplTokenSingleOperation; -impl crate::ExApiInstructionExecutor for crate::ExSplToken2022Executor { - fn executor_name(&self) -> &'static str { - return "kb_executor_spl_token2022"; - } - - fn executor_version(&self) -> &'static str { - return env!("CARGO_PKG_VERSION"); - } - - fn program_ids(&self) -> &'static [&'static str] { - return &[kb_program_ids::SPL_TOKEN2022_PROGRAM_ID]; - } - - fn supports_request( - &self, - request: &crate::ExApiExecutionRequest, - ) -> crate::ExApiExecutionSupport { - 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 { - let payload_json = match crate::executor_api_serialize_payload_json( - &serde_json::json!({"status":"reserved_executor","surface":"spl_token2022"}), - ) { - 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_token2022".to_string(), - instruction_count: 0, - payload_json, - }); - } -} +/// Internal SPL Token-2022 prepared-plan builder. +pub(crate) use self::builder::executor_spl_token2022_build_prepared_plan; +/// Maximum ordered multisig signer occurrences. +pub(crate) use self::constants::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS; +/// Maximum transfer-fee source account count. +pub(crate) use self::constants::EX_SPL_TOKEN2022_MAX_TRANSFER_FEE_SOURCE_ACCOUNTS; +/// Maximum UI amount byte length. +pub(crate) use self::constants::EX_SPL_TOKEN2022_MAX_UI_AMOUNT_BYTES; +/// Canonical SPL Token-2022 tracing target. +pub(crate) use self::constants::EX_SPL_TOKEN2022_TRACING_TARGET; diff --git a/kb-lib/src/executor/spl/token2022/builder.rs b/kb-lib/src/executor/spl/token2022/builder.rs new file mode 100644 index 0000000..f82dd0e --- /dev/null +++ b/kb-lib/src/executor/spl/token2022/builder.rs @@ -0,0 +1,4935 @@ +// file: kb-lib/src/executor/spl/token2022/builder.rs +// version: 27 + +//! Official Token-2022 builders and conservative plan validation. + +use std::str::FromStr; // rust-rules: trait-import + +struct ParsedAuthority { + authority: solana_pubkey::Pubkey, + signers: std::vec::Vec, +} + +pub(crate) fn executor_spl_token2022_build_prepared_plan( + intent: &crate::ExSplToken2022ExecutionIntent, +) -> kb_core::Result { + if intent.intent_id.trim().is_empty() { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_intent_id_empty", + "SPL Token execution intent id must not be empty", + )); + } + let fee_payer = match parse_pubkey(&intent.fee_payer, "fee_payer") { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + match validate_policy(intent) { + std::result::Result::Ok(()) => {}, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + let program_id = match solana_pubkey::Pubkey::from_str(kb_program_ids::SPL_TOKEN2022_PROGRAM_ID) + { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_program_id_invalid", + error.to_string(), + )); + }, + }; + let instruction = match &intent.operation { + crate::ExSplToken2022Operation::Instruction { value } => { + match build_single(&program_id, value) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + }, + crate::ExSplToken2022Operation::Batch { instructions } => { + match build_batch(&program_id, instructions.as_slice()) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + }, + }; + let requested_spend_lamports = match declared_spend_lamports(&intent.operation) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + let planned_instruction = planned_instruction(intent.operation.operation_code(), &instruction); + let required_signers = required_signers(&intent.fee_payer, &instruction.accounts); + tracing::debug!( + target: crate::EX_SPL_TOKEN2022_TRACING_TARGET, + action = "executor_spl_token2022_build_prepared_plan", + intent_id = %intent.intent_id, + operation_code = intent.operation.operation_code(), + program_id = kb_program_ids::SPL_TOKEN2022_PROGRAM_ID, + account_occurrence_count = instruction.accounts.len(), + required_signer_count = required_signers.len(), + requested_spend_lamports, + dry_run = intent.policy.dry_run, + "built Token-2022 execution plan" + ); + return std::result::Result::Ok(crate::ExApiPreparedExecutionPlan { + executor_name: std::string::String::from("kb_executor_spl_token_2022"), + executor_version: std::string::String::from(env!("CARGO_PKG_VERSION")), + intent_id: intent.intent_id.clone(), + operation_code: std::string::String::from(intent.operation.operation_code()), + fee_payer: crate::MdPubkey(fee_payer.to_string()), + instructions: vec![planned_instruction], + required_signers, + policy: intent.policy.clone(), + requested_spend_lamports, + requested_compute_unit_price_micro_lamports: std::option::Option::None, + }); +} + +fn validate_policy(intent: &crate::ExSplToken2022ExecutionIntent) -> kb_core::Result<()> { + if intent.policy.simulation != crate::ExApiExecutionSimulationPolicy::Required { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_simulation_required", + "SPL Token execution requires simulation before signing or sending", + )); + } + match intent.policy.cost_limit.max_fee_lamports { + std::option::Option::Some(limit) if limit > 0 => {}, + std::option::Option::Some(_) | std::option::Option::None => { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_fee_limit_missing", + "SPL Token execution requires a positive transaction fee ceiling", + )); + }, + } + let validation = &intent.policy.post_execution_validation; + if !validation.canonical_insert_required + || !validation.core_extraction_required + || !validation.decode_replay_required + { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_post_validation_required", + "SPL Token execution requires canonical insertion, core extraction and decode replay validation", + )); + } + if intent.operation.requires_materialization() && !validation.materialization_required { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_materialization_validation_required", + "Mutating SPL Token execution requires materialization validation", + )); + } + if has_unbounded_lamport_movement(&intent.operation) && !intent.policy.dry_run { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_stateful_lamport_preflight_required", + "WithdrawExcessLamports and full-balance UnwrapLamports remain simulation-only until a stateful preflight bounds the movable lamports", + )); + } + return std::result::Result::Ok(()); +} + +macro_rules! parse_key { + ($value:expr, $field:expr) => { + match parse_pubkey($value, $field) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + }; +} + +macro_rules! parse_raw_amount { + ($value:expr, $field:expr) => { + match parse_amount($value, $field) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + }; +} + +macro_rules! parse_token_authority { + ($value:expr) => { + match parse_authority($value) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + }; +} + +macro_rules! parse_optional_key { + ($value:expr, $field:expr) => { + match $value { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, $field)) + }, + std::option::Option::None => std::option::Option::None, + } + }; +} + +fn validate_metadata_string(value: &str, field: &str) -> kb_core::Result<()> { + if value.len() > 1_024 { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_metadata_string_too_long", + format!("Token metadata {field} exceeds the 1024-byte executor bound"), + )); + } + return std::result::Result::Ok(()); +} + +fn default_account_state( + state: crate::ExSplTokenDefaultAccountState, +) -> spl_token_2022_interface::state::AccountState { + return match state { + crate::ExSplTokenDefaultAccountState::Initialized => { + spl_token_2022_interface::state::AccountState::Initialized + }, + crate::ExSplTokenDefaultAccountState::Frozen => { + spl_token_2022_interface::state::AccountState::Frozen + }, + }; +} + +#[allow(deprecated)] +fn parse_multiplier(value: &crate::ExSplTokenMultiplier, field: &str) -> kb_core::Result { + let parsed = match value.0.parse::() { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_multiplier_invalid", + format!("{field} must be a decimal f64: {error}"), + )); + }, + }; + if !parsed.is_finite() || !parsed.is_normal() || parsed <= 0.0 { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_multiplier_invalid", + format!("{field} must be positive, finite and normal"), + )); + } + return std::result::Result::Ok(parsed); +} + +#[allow(deprecated)] +fn build_single( + program_id: &solana_pubkey::Pubkey, + operation: &crate::ExSplTokenSingleOperation, +) -> kb_core::Result { + return match operation { + crate::ExSplTokenSingleOperation::InitializeMint { + mint, + mint_authority, + freeze_authority, + decimals, + } => { + let mint = parse_key!(mint, "mint"); + let mint_authority = parse_key!(mint_authority, "mint_authority"); + let freeze_authority = match freeze_authority { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, "freeze_authority")) + }, + std::option::Option::None => std::option::Option::None, + }; + official_instruction(spl_token_2022_interface::instruction::initialize_mint2( + program_id, + &mint, + &mint_authority, + freeze_authority.as_ref(), + *decimals, + )) + }, + crate::ExSplTokenSingleOperation::InitializeAccount { account, mint, owner } => { + let account = parse_key!(account, "account"); + let mint = parse_key!(mint, "mint"); + let owner = parse_key!(owner, "owner"); + official_instruction(spl_token_2022_interface::instruction::initialize_account3( + program_id, &account, &mint, &owner, + )) + }, + crate::ExSplTokenSingleOperation::InitializeMultisig { multisig, members, threshold } => { + if members.is_empty() + || members.len() > crate::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS + || *threshold == 0 + || usize::from(*threshold) > members.len() + { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_multisig_threshold_invalid", + format!( + "SPL Token multisig requires 1..={} members and threshold 1..=N; received M={} N={}", + crate::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS, + threshold, + members.len() + ), + )); + } + let multisig = parse_key!(multisig, "multisig"); + let mut parsed_members = std::vec::Vec::with_capacity(members.len()); + for member in members { + parsed_members.push(parse_key!(member, "multisig_member")); + } + let member_refs = parsed_members.iter().collect::>(); + official_instruction(spl_token_2022_interface::instruction::initialize_multisig2( + program_id, + &multisig, + member_refs.as_slice(), + *threshold, + )) + }, + crate::ExSplTokenSingleOperation::Transfer { source, destination, authority, amount } => { + let source = parse_key!(source, "source"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction(spl_token_2022_interface::instruction::transfer( + program_id, + &source, + &destination, + &authority.authority, + signer_refs.as_slice(), + amount, + )) + }, + crate::ExSplTokenSingleOperation::Approve { source, delegate, authority, amount } => { + let source = parse_key!(source, "source"); + let delegate = parse_key!(delegate, "delegate"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction(spl_token_2022_interface::instruction::approve( + program_id, + &source, + &delegate, + &authority.authority, + signer_refs.as_slice(), + amount, + )) + }, + crate::ExSplTokenSingleOperation::Revoke { source, authority } => { + let source = parse_key!(source, "source"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction(spl_token_2022_interface::instruction::revoke( + program_id, + &source, + &authority.authority, + signer_refs.as_slice(), + )) + }, + crate::ExSplTokenSingleOperation::SetAuthority { + owned, + authority_type, + new_authority, + current_authority, + } => { + let owned = parse_key!(owned, "owned"); + let new_authority = match new_authority { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, "new_authority")) + }, + std::option::Option::None => std::option::Option::None, + }; + let current_authority = parse_token_authority!(current_authority); + let signer_refs = current_authority.signers.iter().collect::>(); + let authority_type = match authority_type { + crate::ExSplTokenAuthorityType::MintTokens => { + spl_token_2022_interface::instruction::AuthorityType::MintTokens + }, + crate::ExSplTokenAuthorityType::FreezeAccount => { + spl_token_2022_interface::instruction::AuthorityType::FreezeAccount + }, + crate::ExSplTokenAuthorityType::AccountOwner => { + spl_token_2022_interface::instruction::AuthorityType::AccountOwner + }, + crate::ExSplTokenAuthorityType::CloseAccount => { + spl_token_2022_interface::instruction::AuthorityType::CloseAccount + }, + }; + official_instruction(spl_token_2022_interface::instruction::set_authority( + program_id, + &owned, + new_authority.as_ref(), + authority_type, + ¤t_authority.authority, + signer_refs.as_slice(), + )) + }, + crate::ExSplTokenSingleOperation::MintTo { mint, destination, authority, amount } => { + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction(spl_token_2022_interface::instruction::mint_to( + program_id, + &mint, + &destination, + &authority.authority, + signer_refs.as_slice(), + amount, + )) + }, + crate::ExSplTokenSingleOperation::Burn { source, mint, authority, amount } => { + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction(spl_token_2022_interface::instruction::burn( + program_id, + &source, + &mint, + &authority.authority, + signer_refs.as_slice(), + amount, + )) + }, + crate::ExSplTokenSingleOperation::CloseAccount { account, destination, authority } => { + let account = parse_key!(account, "account"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction(spl_token_2022_interface::instruction::close_account( + program_id, + &account, + &destination, + &authority.authority, + signer_refs.as_slice(), + )) + }, + crate::ExSplTokenSingleOperation::FreezeAccount { account, mint, authority } => { + let account = parse_key!(account, "account"); + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction(spl_token_2022_interface::instruction::freeze_account( + program_id, + &account, + &mint, + &authority.authority, + signer_refs.as_slice(), + )) + }, + crate::ExSplTokenSingleOperation::ThawAccount { account, mint, authority } => { + let account = parse_key!(account, "account"); + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction(spl_token_2022_interface::instruction::thaw_account( + program_id, + &account, + &mint, + &authority.authority, + signer_refs.as_slice(), + )) + }, + crate::ExSplTokenSingleOperation::TransferChecked { + source, + mint, + destination, + authority, + amount, + decimals, + } => { + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction(spl_token_2022_interface::instruction::transfer_checked( + program_id, + &source, + &mint, + &destination, + &authority.authority, + signer_refs.as_slice(), + amount, + *decimals, + )) + }, + crate::ExSplTokenSingleOperation::ApproveChecked { + source, + mint, + delegate, + authority, + amount, + decimals, + } => { + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let delegate = parse_key!(delegate, "delegate"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction(spl_token_2022_interface::instruction::approve_checked( + program_id, + &source, + &mint, + &delegate, + &authority.authority, + signer_refs.as_slice(), + amount, + *decimals, + )) + }, + crate::ExSplTokenSingleOperation::MintToChecked { + mint, + destination, + authority, + amount, + decimals, + } => { + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction(spl_token_2022_interface::instruction::mint_to_checked( + program_id, + &mint, + &destination, + &authority.authority, + signer_refs.as_slice(), + amount, + *decimals, + )) + }, + crate::ExSplTokenSingleOperation::BurnChecked { + source, + mint, + authority, + amount, + decimals, + } => { + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction(spl_token_2022_interface::instruction::burn_checked( + program_id, + &source, + &mint, + &authority.authority, + signer_refs.as_slice(), + amount, + *decimals, + )) + }, + crate::ExSplTokenSingleOperation::SyncNative { account, include_rent_sysvar } => { + let account = parse_key!(account, "account"); + if *include_rent_sysvar { + official_instruction( + spl_token_2022_interface::instruction::sync_native_with_rent_sysvar( + program_id, &account, + ), + ) + } else { + official_instruction(spl_token_2022_interface::instruction::sync_native( + program_id, &account, + )) + } + }, + crate::ExSplTokenSingleOperation::GetAccountDataSize { mint } => { + let mint = parse_key!(mint, "mint"); + official_instruction(spl_token_2022_interface::instruction::get_account_data_size( + program_id, + &mint, + &[], + )) + }, + crate::ExSplTokenSingleOperation::InitializeImmutableOwner { account } => { + let account = parse_key!(account, "account"); + official_instruction(spl_token_2022_interface::instruction::initialize_immutable_owner( + program_id, &account, + )) + }, + crate::ExSplTokenSingleOperation::AmountToUiAmount { mint, amount } => { + let mint = parse_key!(mint, "mint"); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction(spl_token_2022_interface::instruction::amount_to_ui_amount( + program_id, &mint, amount, + )) + }, + crate::ExSplTokenSingleOperation::UiAmountToAmount { mint, ui_amount } => { + if ui_amount.len() > crate::EX_SPL_TOKEN2022_MAX_UI_AMOUNT_BYTES { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_ui_amount_too_large", + format!( + "SPL Token UI amount length {} exceeds {} bytes", + ui_amount.len(), + crate::EX_SPL_TOKEN2022_MAX_UI_AMOUNT_BYTES + ), + )); + } + let mint = parse_key!(mint, "mint"); + official_instruction(spl_token_2022_interface::instruction::ui_amount_to_amount( + program_id, + &mint, + ui_amount.as_str(), + )) + }, + crate::ExSplTokenSingleOperation::WithdrawExcessLamports { + account, + destination, + authority, + } => { + let account = parse_key!(account, "account"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction(spl_token_2022_interface::instruction::withdraw_excess_lamports( + program_id, + &account, + &destination, + &authority.authority, + signer_refs.as_slice(), + )) + }, + crate::ExSplTokenSingleOperation::Reallocate { + account, + payer, + authority, + extension_types, + } => { + let account = parse_key!(account, "account"); + let payer = parse_key!(payer, "payer"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let mut parsed_extension_types = std::vec::Vec::with_capacity(extension_types.len()); + for extension_type in extension_types { + let parsed = match spl_token_2022_interface::extension::ExtensionType::try_from( + *extension_type, + ) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(_) => { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_extension_type_unknown", + format!("unknown Token-2022 extension type {extension_type}"), + )); + }, + }; + parsed_extension_types.push(parsed); + } + official_instruction(spl_token_2022_interface::instruction::reallocate( + program_id, + &account, + &payer, + &authority.authority, + signer_refs.as_slice(), + parsed_extension_types.as_slice(), + )) + }, + crate::ExSplTokenSingleOperation::InitializeNonTransferableMint { mint } => { + let mint = parse_key!(mint, "mint"); + official_instruction( + spl_token_2022_interface::instruction::initialize_non_transferable_mint( + program_id, &mint, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializePermanentDelegate { mint, delegate } => { + let mint = parse_key!(mint, "mint"); + let delegate = parse_key!(delegate, "delegate"); + official_instruction( + spl_token_2022_interface::instruction::initialize_permanent_delegate( + program_id, &mint, &delegate, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeInterestBearingMint { + mint, + rate_authority, + rate_basis_points, + } => { + let mint = parse_key!(mint, "mint"); + let rate_authority = match rate_authority { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, "rate_authority")) + }, + std::option::Option::None => std::option::Option::None, + }; + official_instruction( + spl_token_2022_interface::extension::interest_bearing_mint::instruction::initialize( + program_id, + &mint, + rate_authority, + *rate_basis_points, + ), + ) + }, + crate::ExSplTokenSingleOperation::UpdateInterestBearingRate { + mint, + authority, + rate_basis_points, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::interest_bearing_mint::instruction::update_rate( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + *rate_basis_points, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeTransferFeeConfig { + mint, + transfer_fee_config_authority, + withdraw_withheld_authority, + transfer_fee_basis_points, + maximum_fee, + } => { + if *transfer_fee_basis_points + > spl_token_2022_interface::extension::transfer_fee::MAX_FEE_BASIS_POINTS + { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_transfer_fee_basis_points_invalid", + format!( + "transfer fee basis points {} exceed {}", + transfer_fee_basis_points, + spl_token_2022_interface::extension::transfer_fee::MAX_FEE_BASIS_POINTS + ), + )); + } + let mint = parse_key!(mint, "mint"); + let config_authority = match transfer_fee_config_authority { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, "transfer_fee_config_authority")) + }, + std::option::Option::None => std::option::Option::None, + }; + let withdraw_authority = match withdraw_withheld_authority { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, "withdraw_withheld_authority")) + }, + std::option::Option::None => std::option::Option::None, + }; + let maximum_fee = parse_raw_amount!(maximum_fee, "maximum_fee"); + official_instruction( + spl_token_2022_interface::extension::transfer_fee::instruction::initialize_transfer_fee_config( + program_id, + &mint, + config_authority.as_ref(), + withdraw_authority.as_ref(), + *transfer_fee_basis_points, + maximum_fee, + ), + ) + }, + crate::ExSplTokenSingleOperation::SetTransferFee { + mint, + authority, + transfer_fee_basis_points, + maximum_fee, + } => { + if *transfer_fee_basis_points + > spl_token_2022_interface::extension::transfer_fee::MAX_FEE_BASIS_POINTS + { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_transfer_fee_basis_points_invalid", + "transfer fee basis points exceed the official maximum", + )); + } + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let maximum_fee = parse_raw_amount!(maximum_fee, "maximum_fee"); + official_instruction( + spl_token_2022_interface::extension::transfer_fee::instruction::set_transfer_fee( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + *transfer_fee_basis_points, + maximum_fee, + ), + ) + }, + crate::ExSplTokenSingleOperation::TransferCheckedWithFee { + source, + mint, + destination, + authority, + amount, + decimals, + fee, + } => { + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + let fee = parse_raw_amount!(fee, "fee"); + official_instruction( + spl_token_2022_interface::extension::transfer_fee::instruction::transfer_checked_with_fee( + program_id, + &source, + &mint, + &destination, + &authority.authority, + signer_refs.as_slice(), + amount, + *decimals, + fee, + ), + ) + }, + crate::ExSplTokenSingleOperation::WithdrawWithheldTokensFromMint { + mint, + destination, + authority, + } => { + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::transfer_fee::instruction::withdraw_withheld_tokens_from_mint( + program_id, + &mint, + &destination, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::WithdrawWithheldTokensFromAccounts { + mint, + destination, + authority, + sources, + } => { + let sources = match parse_transfer_fee_sources(sources) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + let source_refs = sources.iter().collect::>(); + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::transfer_fee::instruction::withdraw_withheld_tokens_from_accounts( + program_id, + &mint, + &destination, + &authority.authority, + signer_refs.as_slice(), + source_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::HarvestWithheldTokensToMint { mint, sources } => { + let sources = match parse_transfer_fee_sources(sources) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + let source_refs = sources.iter().collect::>(); + let mint = parse_key!(mint, "mint"); + official_instruction( + spl_token_2022_interface::extension::transfer_fee::instruction::harvest_withheld_tokens_to_mint( + program_id, + &mint, + source_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeDefaultAccountState { mint, state } => { + let mint = parse_key!(mint, "mint"); + let state = default_account_state(*state); + official_instruction( + spl_token_2022_interface::extension::default_account_state::instruction::initialize_default_account_state( + program_id, + &mint, + &state, + ), + ) + }, + crate::ExSplTokenSingleOperation::UpdateDefaultAccountState { mint, authority, state } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let state = default_account_state(*state); + official_instruction( + spl_token_2022_interface::extension::default_account_state::instruction::update_default_account_state( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + &state, + ), + ) + }, + crate::ExSplTokenSingleOperation::EnableRequiredTransferMemos { account, authority } => { + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::memo_transfer::instruction::enable_required_transfer_memos( + program_id, + &account, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::DisableRequiredTransferMemos { account, authority } => { + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::memo_transfer::instruction::disable_required_transfer_memos( + program_id, + &account, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::EnableCpiGuard { account, authority } => { + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::cpi_guard::instruction::enable_cpi_guard( + program_id, + &account, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::DisableCpiGuard { account, authority } => { + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::cpi_guard::instruction::disable_cpi_guard( + program_id, + &account, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeTransferHook { + mint, + authority, + program_id: hook_program_id, + } => { + let mint = parse_key!(mint, "mint"); + let authority = match authority { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, "transfer_hook_authority")) + }, + std::option::Option::None => std::option::Option::None, + }; + let hook_program_id = match hook_program_id { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, "transfer_hook_program_id")) + }, + std::option::Option::None => std::option::Option::None, + }; + official_instruction( + spl_token_2022_interface::extension::transfer_hook::instruction::initialize( + program_id, + &mint, + authority, + hook_program_id, + ), + ) + }, + crate::ExSplTokenSingleOperation::UpdateTransferHook { + mint, + authority, + program_id: hook_program_id, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let hook_program_id = match hook_program_id { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, "transfer_hook_program_id")) + }, + std::option::Option::None => std::option::Option::None, + }; + official_instruction( + spl_token_2022_interface::extension::transfer_hook::instruction::update( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + hook_program_id, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeMetadataPointer { + mint, + authority, + metadata_address, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_optional_key!(authority, "metadata_pointer_authority"); + let metadata_address = parse_optional_key!(metadata_address, "metadata_address"); + official_instruction( + spl_token_2022_interface::extension::metadata_pointer::instruction::initialize( + program_id, + &mint, + authority, + metadata_address, + ), + ) + }, + crate::ExSplTokenSingleOperation::UpdateMetadataPointer { + mint, + authority, + metadata_address, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let metadata_address = parse_optional_key!(metadata_address, "metadata_address"); + official_instruction( + spl_token_2022_interface::extension::metadata_pointer::instruction::update( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + metadata_address, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeGroupPointer { + mint, + authority, + group_address, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_optional_key!(authority, "group_pointer_authority"); + let group_address = parse_optional_key!(group_address, "group_address"); + official_instruction( + spl_token_2022_interface::extension::group_pointer::instruction::initialize( + program_id, + &mint, + authority, + group_address, + ), + ) + }, + crate::ExSplTokenSingleOperation::UpdateGroupPointer { mint, authority, group_address } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let group_address = parse_optional_key!(group_address, "group_address"); + official_instruction( + spl_token_2022_interface::extension::group_pointer::instruction::update( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + group_address, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeGroupMemberPointer { + mint, + authority, + member_address, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_optional_key!(authority, "group_member_pointer_authority"); + let member_address = parse_optional_key!(member_address, "group_member_address"); + official_instruction( + spl_token_2022_interface::extension::group_member_pointer::instruction::initialize( + program_id, + &mint, + authority, + member_address, + ), + ) + }, + crate::ExSplTokenSingleOperation::UpdateGroupMemberPointer { + mint, + authority, + member_address, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let member_address = parse_optional_key!(member_address, "group_member_address"); + official_instruction( + spl_token_2022_interface::extension::group_member_pointer::instruction::update( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + member_address, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeTokenMetadata { + metadata, + update_authority, + mint, + mint_authority, + name, + symbol, + uri, + } => { + match validate_metadata_string(name, "name") { + std::result::Result::Ok(()) => {}, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + match validate_metadata_string(symbol, "symbol") { + std::result::Result::Ok(()) => {}, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + match validate_metadata_string(uri, "uri") { + std::result::Result::Ok(()) => {}, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + let metadata = parse_key!(metadata, "metadata"); + let update_authority = parse_key!(update_authority, "update_authority"); + let mint = parse_key!(mint, "mint"); + let mint_authority = parse_key!(mint_authority, "mint_authority"); + std::result::Result::Ok(spl_token_metadata_interface::instruction::initialize( + program_id, + &metadata, + &update_authority, + &mint, + &mint_authority, + name.clone(), + symbol.clone(), + uri.clone(), + )) + }, + crate::ExSplTokenSingleOperation::UpdateTokenMetadataField { + metadata, + update_authority, + field, + value, + } => { + match validate_metadata_string(value, "value") { + std::result::Result::Ok(()) => {}, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + let metadata = parse_key!(metadata, "metadata"); + let update_authority = parse_key!(update_authority, "update_authority"); + let field = match field { + crate::ExSplTokenMetadataField::Name => { + spl_token_metadata_interface::state::Field::Name + }, + crate::ExSplTokenMetadataField::Symbol => { + spl_token_metadata_interface::state::Field::Symbol + }, + crate::ExSplTokenMetadataField::Uri => { + spl_token_metadata_interface::state::Field::Uri + }, + crate::ExSplTokenMetadataField::Key(key) => { + match validate_metadata_string(key, "key") { + std::result::Result::Ok(()) => {}, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + spl_token_metadata_interface::state::Field::Key(key.clone()) + }, + }; + std::result::Result::Ok(spl_token_metadata_interface::instruction::update_field( + program_id, + &metadata, + &update_authority, + field, + value.clone(), + )) + }, + crate::ExSplTokenSingleOperation::RemoveTokenMetadataKey { + metadata, + update_authority, + key, + idempotent, + } => { + match validate_metadata_string(key, "key") { + std::result::Result::Ok(()) => {}, + std::result::Result::Err(error) => return std::result::Result::Err(error), + } + let metadata = parse_key!(metadata, "metadata"); + let update_authority = parse_key!(update_authority, "update_authority"); + std::result::Result::Ok(spl_token_metadata_interface::instruction::remove_key( + program_id, + &metadata, + &update_authority, + key.clone(), + *idempotent, + )) + }, + crate::ExSplTokenSingleOperation::InitializeTokenGroup { + group, + mint, + mint_authority, + update_authority, + max_size, + } => { + let group = parse_key!(group, "group"); + let mint = parse_key!(mint, "mint"); + let mint_authority = parse_key!(mint_authority, "mint_authority"); + let update_authority = parse_optional_key!(update_authority, "group_update_authority"); + std::result::Result::Ok(spl_token_group_interface::instruction::initialize_group( + program_id, + &group, + &mint, + &mint_authority, + update_authority, + *max_size, + )) + }, + crate::ExSplTokenSingleOperation::UpdateTokenGroupMaxSize { + group, + update_authority, + max_size, + } => { + let group = parse_key!(group, "group"); + let update_authority = parse_key!(update_authority, "group_update_authority"); + std::result::Result::Ok(spl_token_group_interface::instruction::update_group_max_size( + program_id, + &group, + &update_authority, + *max_size, + )) + }, + crate::ExSplTokenSingleOperation::InitializeTokenGroupMember { + member, + member_mint, + member_mint_authority, + group, + group_update_authority, + } => { + let member = parse_key!(member, "member"); + let member_mint = parse_key!(member_mint, "member_mint"); + let member_mint_authority = parse_key!(member_mint_authority, "member_mint_authority"); + let group = parse_key!(group, "group"); + let group_update_authority = + parse_key!(group_update_authority, "group_update_authority"); + std::result::Result::Ok(spl_token_group_interface::instruction::initialize_member( + program_id, + &member, + &member_mint, + &member_mint_authority, + &group, + &group_update_authority, + )) + }, + crate::ExSplTokenSingleOperation::InitializeScaledUiAmount { + mint, + authority, + multiplier, + } => { + let mint = parse_key!(mint, "mint"); + let authority = match authority { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_key!(value, "authority")) + }, + std::option::Option::None => std::option::Option::None, + }; + let multiplier = match parse_multiplier(multiplier, "multiplier") { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + official_instruction( + spl_token_2022_interface::extension::scaled_ui_amount::instruction::initialize( + program_id, &mint, authority, multiplier, + ), + ) + }, + crate::ExSplTokenSingleOperation::UpdateScaledUiAmountMultiplier { + mint, + authority, + multiplier, + effective_timestamp, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let multiplier = match parse_multiplier(multiplier, "multiplier") { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + official_instruction( + spl_token_2022_interface::extension::scaled_ui_amount::instruction::update_multiplier( + program_id, &mint, &authority.authority, signer_refs.as_slice(), multiplier, *effective_timestamp, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializePausableConfig { mint, authority } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_key!(authority, "authority"); + official_instruction( + spl_token_2022_interface::extension::pausable::instruction::initialize( + program_id, &mint, &authority, + ), + ) + }, + crate::ExSplTokenSingleOperation::Pause { mint, authority } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction(spl_token_2022_interface::extension::pausable::instruction::pause( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + )) + }, + crate::ExSplTokenSingleOperation::Resume { mint, authority } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::pausable::instruction::resume( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializePermissionedBurn { mint, authority } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_key!(authority, "authority"); + official_instruction( + spl_token_2022_interface::extension::permissioned_burn::instruction::initialize( + program_id, &mint, &authority, + ), + ) + }, + crate::ExSplTokenSingleOperation::PermissionedBurn { + source, + mint, + permissioned_burn_authority, + authority, + amount, + } => { + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let permissioned_burn_authority = + parse_key!(permissioned_burn_authority, "permissioned_burn_authority"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction( + spl_token_2022_interface::extension::permissioned_burn::instruction::burn( + program_id, + &source, + &mint, + &permissioned_burn_authority, + &authority.authority, + signer_refs.as_slice(), + amount, + ), + ) + }, + crate::ExSplTokenSingleOperation::PermissionedBurnChecked { + source, + mint, + permissioned_burn_authority, + authority, + amount, + decimals, + } => { + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let permissioned_burn_authority = + parse_key!(permissioned_burn_authority, "permissioned_burn_authority"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction( + spl_token_2022_interface::extension::permissioned_burn::instruction::burn_checked( + program_id, + &source, + &mint, + &permissioned_burn_authority, + &authority.authority, + signer_refs.as_slice(), + amount, + *decimals, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeConfidentialTransferMint { + mint, + authority, + auto_approve_new_accounts, + auditor_elgamal_pubkey, + } => { + let mint = parse_key!(mint, "mint"); + let authority = match authority { + Some(value) => Some(parse_key!(value, "authority")), + None => None, + }; + let auditor_elgamal_pubkey = match auditor_elgamal_pubkey { + Some(value) => match value.parse() { + Ok(parsed) => Some(parsed), + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_elgamal_pubkey", + error, + )); + }, + }, + None => None, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::initialize_mint( + program_id, &mint, authority, *auto_approve_new_accounts, auditor_elgamal_pubkey, + ), + ) + }, + crate::ExSplTokenSingleOperation::UpdateConfidentialTransferMint { + mint, + authority, + auto_approve_new_accounts, + auditor_elgamal_pubkey, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let auditor_elgamal_pubkey = match auditor_elgamal_pubkey { + Some(value) => match value.parse() { + Ok(parsed) => Some(parsed), + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_elgamal_pubkey", + error, + )); + }, + }, + None => None, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::update_mint( + program_id, &mint, &authority.authority, signer_refs.as_slice(), + *auto_approve_new_accounts, auditor_elgamal_pubkey, + ), + ) + }, + crate::ExSplTokenSingleOperation::ApplyPendingConfidentialBalance { + account, + expected_pending_balance_credit_counter, + new_decryptable_available_balance, + authority, + } => { + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let balance = match new_decryptable_available_balance.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_decryptable_balance", + error, + )); + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::apply_pending_balance( + program_id, &account, *expected_pending_balance_credit_counter, &balance, + &authority.authority, signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::ApproveConfidentialTransferAccount { + account, + mint, + authority, + } => { + let account = parse_key!(account, "account"); + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::approve_account( + program_id, &account, &mint, &authority.authority, signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::DepositConfidentialTokens { + account, + mint, + authority, + amount, + decimals, + } => { + let account = parse_key!(account, "account"); + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount = parse_raw_amount!(amount, "amount"); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::deposit( + program_id, + &account, + &mint, + amount, + *decimals, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::EnableConfidentialCredits { account, authority } => { + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::enable_confidential_credits( + program_id, &account, &authority.authority, signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::DisableConfidentialCredits { account, authority } => { + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::disable_confidential_credits( + program_id, &account, &authority.authority, signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::EnableNonConfidentialCredits { account, authority } => { + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::enable_non_confidential_credits( + program_id, &account, &authority.authority, signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::DisableNonConfidentialCredits { account, authority } => { + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::disable_non_confidential_credits( + program_id, &account, &authority.authority, signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::ConfigureConfidentialTransferAccount { + account, + mint, + decryptable_zero_balance, + maximum_pending_balance_credit_counter, + authority, + proof, + } => { + if proof.kind != crate::ExSplTokenConfidentialProofKind::PubkeyValidity { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "ConfigureAccount requires exactly one PubkeyValidity proof reference", + )); + } + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + let account = parse_key!(account, "account"); + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let decryptable_zero_balance = match decryptable_zero_balance.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_decryptable_balance", + error, + )); + }, + }; + let proof_data = ::zeroed(); + let context_account; + let proof_location = match &proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "ConfigureAccount inline proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &proof_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + context_account = parse_key!(account, "proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&context_account) + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::inner_configure_account( + program_id, + &account, + &mint, + &decryptable_zero_balance, + *maximum_pending_balance_credit_counter, + &authority.authority, + signer_refs.as_slice(), + proof_location, + ), + ) + }, + crate::ExSplTokenSingleOperation::ConfigureConfidentialTransferAccountWithRegistry { + account, + mint, + registry_account, + payer, + } => { + let account = parse_key!(account, "account"); + let mint = parse_key!(mint, "mint"); + let registry_account = parse_key!(registry_account, "registry_account"); + let payer = match payer { + Some(value) => Some(parse_key!(value, "payer")), + None => None, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::configure_account_with_registry( + program_id, + &account, + &mint, + ®istry_account, + payer.as_ref(), + ), + ) + }, + crate::ExSplTokenSingleOperation::EmptyConfidentialTransferAccount { + account, + authority, + proof, + } => { + if proof.kind != crate::ExSplTokenConfidentialProofKind::ZeroCiphertext { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "EmptyAccount requires exactly one ZeroCiphertext proof reference", + )); + } + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + let account = parse_key!(account, "account"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let proof_data = ::zeroed(); + let context_account; + let proof_location = match &proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "EmptyAccount inline proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &proof_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + context_account = parse_key!(account, "proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&context_account) + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::inner_empty_account( + program_id, + &account, + &authority.authority, + signer_refs.as_slice(), + proof_location, + ), + ) + }, + crate::ExSplTokenSingleOperation::WithdrawConfidentialTokens { + account, + mint, + amount, + decimals, + new_decryptable_available_balance, + authority, + equality_proof, + range_proof, + } => { + if equality_proof.kind + != crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality + || range_proof.kind != crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU64 + { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "Withdraw requires CiphertextCommitmentEquality then BatchedRangeProofU64 proof references", + )); + } + for proof in [equality_proof, range_proof] { + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + } + let account = parse_key!(account, "account"); + let mint = parse_key!(mint, "mint"); + let amount = parse_raw_amount!(amount, "amount"); + let new_balance = match new_decryptable_available_balance.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_decryptable_balance_invalid", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let equality_data = ::zeroed(); + let range_data = ::zeroed(); + let equality_context; + let range_context; + let equality_location = match &equality_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Withdraw equality proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &equality_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + equality_context = parse_key!(account, "equality_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&equality_context) + }, + }; + let range_location = match &range_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Withdraw range proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &range_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + range_context = parse_key!(account, "range_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&range_context) + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::inner_withdraw( + program_id, + &account, + &mint, + amount, + *decimals, + &new_balance, + &authority.authority, + signer_refs.as_slice(), + equality_location, + range_location, + ), + ) + }, + crate::ExSplTokenSingleOperation::TransferConfidentialTokens { + source, + mint, + destination, + new_source_decryptable_available_balance, + transfer_amount_auditor_ciphertext_lo, + transfer_amount_auditor_ciphertext_hi, + authority, + equality_proof, + ciphertext_validity_proof, + range_proof, + } => { + if equality_proof.kind != crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality + || ciphertext_validity_proof.kind != crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity + || range_proof.kind != crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU128 + { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "Transfer requires CiphertextCommitmentEquality, BatchedGroupedCiphertext3HandlesValidity, then BatchedRangeProofU128 proof references", + )); + } + for proof in [equality_proof, ciphertext_validity_proof, range_proof] { + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + } + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let new_balance = match new_source_decryptable_available_balance.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_decryptable_balance_invalid", + error, + )); + }, + }; + let auditor_ciphertext_lo = match transfer_amount_auditor_ciphertext_lo.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let auditor_ciphertext_hi = match transfer_amount_auditor_ciphertext_hi.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let equality_data = ::zeroed(); + let validity_data = ::zeroed(); + let range_data = ::zeroed(); + let equality_context; + let validity_context; + let range_context; + let equality_location = match &equality_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Transfer equality proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &equality_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + equality_context = parse_key!(account, "equality_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&equality_context) + }, + }; + let validity_location = match &ciphertext_validity_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Transfer ciphertext-validity proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &validity_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + validity_context = + parse_key!(account, "ciphertext_validity_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&validity_context) + }, + }; + let range_location = match &range_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Transfer range proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &range_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + range_context = parse_key!(account, "range_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&range_context) + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::inner_transfer( + program_id, + &source, + &mint, + &destination, + &new_balance, + &auditor_ciphertext_lo, + &auditor_ciphertext_hi, + &authority.authority, + signer_refs.as_slice(), + equality_location, + validity_location, + range_location, + ), + ) + }, + crate::ExSplTokenSingleOperation::TransferConfidentialTokensWithFee { + source, + mint, + destination, + new_source_decryptable_available_balance, + transfer_amount_auditor_ciphertext_lo, + transfer_amount_auditor_ciphertext_hi, + authority, + equality_proof, + transfer_amount_ciphertext_validity_proof, + fee_sigma_proof, + fee_ciphertext_validity_proof, + range_proof, + } => { + let expected = [ + crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + crate::ExSplTokenConfidentialProofKind::PercentageWithFee, + crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext2HandlesValidity, + crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU256, + ]; + let proofs = [ + equality_proof, + transfer_amount_ciphertext_validity_proof, + fee_sigma_proof, + fee_ciphertext_validity_proof, + range_proof, + ]; + for (proof, kind) in proofs.iter().zip(expected.iter()) { + if proof.kind != *kind { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "TransferWithFee requires Equality, 3-handles validity, PercentageWithFee, 2-handles validity, then U256 range proof references", + )); + } + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + } + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let new_balance = match new_source_decryptable_available_balance.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_decryptable_balance_invalid", + error, + )); + }, + }; + let auditor_ciphertext_lo = match transfer_amount_auditor_ciphertext_lo.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let auditor_ciphertext_hi = match transfer_amount_auditor_ciphertext_hi.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let equality_data = ::zeroed(); + let transfer_validity_data = ::zeroed(); + let fee_sigma_data = ::zeroed(); + let fee_validity_data = ::zeroed(); + let range_data = ::zeroed(); + let equality_context; + let transfer_validity_context; + let fee_sigma_context; + let fee_validity_context; + let range_context; + macro_rules! proof_location { + ($proof:expr, $data:expr, $context:ident, $field:literal) => {{ + match &$proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => return Err(kb_core::Error::new("execution_spl_token_2022_confidential_proof_offset_invalid", concat!($field, " offset must be non-zero"))), + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, $data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + $context = parse_key!(account, concat!($field, "_context_state_account")); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&$context) + }, + } + }}; + } + let equality_location = + proof_location!(equality_proof, &equality_data, equality_context, "equality_proof"); + let transfer_validity_location = proof_location!( + transfer_amount_ciphertext_validity_proof, + &transfer_validity_data, + transfer_validity_context, + "transfer_validity_proof" + ); + let fee_sigma_location = proof_location!( + fee_sigma_proof, + &fee_sigma_data, + fee_sigma_context, + "fee_sigma_proof" + ); + let fee_validity_location = proof_location!( + fee_ciphertext_validity_proof, + &fee_validity_data, + fee_validity_context, + "fee_validity_proof" + ); + let range_location = + proof_location!(range_proof, &range_data, range_context, "range_proof"); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer::instruction::inner_transfer_with_fee( + program_id, &source, &mint, &destination, &new_balance, + &auditor_ciphertext_lo, &auditor_ciphertext_hi, &authority.authority, + signer_refs.as_slice(), equality_location, transfer_validity_location, + fee_sigma_location, fee_validity_location, range_location, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeConfidentialTransferFeeConfig { + mint, + authority, + withdraw_withheld_authority_elgamal_pubkey, + } => { + let mint = parse_key!(mint, "mint"); + let authority = match authority { + Some(value) => Some(parse_key!(value, "authority")), + None => None, + }; + let withdraw_key = match withdraw_withheld_authority_elgamal_pubkey.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_elgamal_pubkey", + error, + )); + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer_fee::instruction::initialize_confidential_transfer_fee_config( + program_id, + &mint, + authority, + &withdraw_key, + ), + ) + }, + crate::ExSplTokenSingleOperation::EnableConfidentialTransferFeeHarvest { + mint, + authority, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer_fee::instruction::enable_harvest_to_mint( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::DisableConfidentialTransferFeeHarvest { + mint, + authority, + } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer_fee::instruction::disable_harvest_to_mint( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::HarvestConfidentialWithheldTokensToMint { + mint, + sources, + } => { + let sources = match parse_transfer_fee_sources(sources) { + Ok(value) => value, + Err(error) => return Err(error), + }; + let source_refs = sources.iter().collect::>(); + let mint = parse_key!(mint, "mint"); + official_instruction( + spl_token_2022_interface::extension::confidential_transfer_fee::instruction::harvest_withheld_tokens_to_mint( + program_id, + &mint, + source_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::WithdrawConfidentialWithheldTokensFromMint { + mint, + destination, + new_decryptable_available_balance, + authority, + proof, + } => { + if proof.kind != crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "confidential fee withdraw from mint requires exactly one CiphertextCiphertextEquality proof reference", + )); + } + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let new_balance = match new_decryptable_available_balance.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_decryptable_balance", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let proof_data = ::zeroed(); + let context_account; + let proof_location = match &proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "confidential fee withdraw from mint inline proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &proof_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + context_account = parse_key!(account, "proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&context_account) + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer_fee::instruction::inner_withdraw_withheld_tokens_from_mint( + program_id, + &mint, + &destination, + &new_balance, + &authority.authority, + signer_refs.as_slice(), + proof_location, + ), + ) + }, + crate::ExSplTokenSingleOperation::WithdrawConfidentialWithheldTokensFromAccounts { + mint, + destination, + new_decryptable_available_balance, + authority, + sources, + proof, + } => { + if proof.kind != crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "confidential fee withdraw from accounts requires exactly one CiphertextCiphertextEquality proof reference", + )); + } + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + let sources = match parse_transfer_fee_sources(sources) { + Ok(value) => value, + Err(error) => return Err(error), + }; + let source_refs = sources.iter().collect::>(); + let mint = parse_key!(mint, "mint"); + let destination = parse_key!(destination, "destination"); + let new_balance = match new_decryptable_available_balance.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_decryptable_balance", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let proof_data = ::zeroed(); + let context_account; + let proof_location = match &proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "confidential fee withdraw from accounts inline proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &proof_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + context_account = parse_key!(account, "proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&context_account) + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_transfer_fee::instruction::inner_withdraw_withheld_tokens_from_accounts( + program_id, + &mint, + &destination, + &new_balance, + &authority.authority, + signer_refs.as_slice(), + source_refs.as_slice(), + proof_location, + ), + ) + }, + crate::ExSplTokenSingleOperation::InitializeConfidentialMintBurnMint { + mint, + supply_elgamal_pubkey, + decryptable_supply, + } => { + let mint = parse_key!(mint, "mint"); + let supply_key = match supply_elgamal_pubkey.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_elgamal_pubkey", + error, + )); + }, + }; + let decryptable_supply = match decryptable_supply.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_decryptable_balance", + error, + )); + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_mint_burn::instruction::initialize_mint( + program_id, + &mint, + &supply_key, + &decryptable_supply, + ), + ) + }, + crate::ExSplTokenSingleOperation::RotateConfidentialSupplyElGamalPubkey { + mint, + new_supply_elgamal_pubkey, + authority, + proof, + } => { + if proof.kind != crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "confidential supply-key rotation requires exactly one CiphertextCiphertextEquality proof reference", + )); + } + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + let mint = parse_key!(mint, "mint"); + let new_supply_key = match new_supply_elgamal_pubkey.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_elgamal_pubkey", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let proof_data = ::zeroed(); + let context_account; + let proof_location = match &proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "confidential supply-key rotation inline proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &proof_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + context_account = parse_key!(account, "proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&context_account) + }, + }; + let instructions = match spl_token_2022_interface::extension::confidential_mint_burn::instruction::rotate_supply_elgamal_pubkey( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + &new_supply_key, + proof_location, + ) { + Ok(value) => value, + Err(error) => return Err(kb_core::Error::new( + "execution_spl_token_2022_official_builder_failed", + error.to_string(), + )), + }; + match instructions.into_iter().next() { + Some(value) => Ok(value), + None => Err(kb_core::Error::new( + "execution_spl_token_2022_official_builder_empty", + "official confidential supply-key rotation builder returned no instruction", + )), + } + }, + crate::ExSplTokenSingleOperation::UpdateConfidentialDecryptableSupply { + mint, + new_decryptable_supply, + authority, + } => { + let mint = parse_key!(mint, "mint"); + let new_supply = match new_decryptable_supply.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_decryptable_balance", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::confidential_mint_burn::instruction::update_decryptable_supply( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + &new_supply, + ), + ) + }, + crate::ExSplTokenSingleOperation::ApplyPendingConfidentialBurn { mint, authority } => { + let mint = parse_key!(mint, "mint"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + official_instruction( + spl_token_2022_interface::extension::confidential_mint_burn::instruction::apply_pending_burn( + program_id, + &mint, + &authority.authority, + signer_refs.as_slice(), + ), + ) + }, + crate::ExSplTokenSingleOperation::ConfidentialMint { + destination, + mint, + new_decryptable_supply, + mint_amount_auditor_ciphertext_lo, + mint_amount_auditor_ciphertext_hi, + authority, + equality_proof, + ciphertext_validity_proof, + range_proof, + } => { + if equality_proof.kind != crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality + || ciphertext_validity_proof.kind != crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity + || range_proof.kind != crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU128 + { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "Confidential Mint requires CiphertextCommitmentEquality, BatchedGroupedCiphertext3HandlesValidity, then BatchedRangeProofU128 proof references", + )); + } + for proof in [equality_proof, ciphertext_validity_proof, range_proof] { + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + } + let destination = parse_key!(destination, "destination"); + let mint = parse_key!(mint, "mint"); + let new_supply = match new_decryptable_supply.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_decryptable_balance", + error, + )); + }, + }; + let auditor_ciphertext_lo = match mint_amount_auditor_ciphertext_lo.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let auditor_ciphertext_hi = match mint_amount_auditor_ciphertext_hi.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let equality_data = ::zeroed(); + let validity_data = ::zeroed(); + let range_data = ::zeroed(); + let equality_context; + let validity_context; + let range_context; + let equality_location = match &equality_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Confidential Mint equality proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &equality_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + equality_context = parse_key!(account, "equality_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&equality_context) + }, + }; + let validity_location = match &ciphertext_validity_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Confidential Mint ciphertext-validity proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &validity_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + validity_context = + parse_key!(account, "ciphertext_validity_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&validity_context) + }, + }; + let range_location = match &range_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Confidential Mint range proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &range_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + range_context = parse_key!(account, "range_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&range_context) + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_mint_burn::instruction::inner_confidential_mint( + program_id, + &destination, + &mint, + &auditor_ciphertext_lo, + &auditor_ciphertext_hi, + &authority.authority, + signer_refs.as_slice(), + equality_location, + validity_location, + range_location, + &new_supply, + ), + ) + }, + crate::ExSplTokenSingleOperation::ConfidentialBurn { + source, + mint, + new_decryptable_available_balance, + burn_amount_auditor_ciphertext_lo, + burn_amount_auditor_ciphertext_hi, + authority, + equality_proof, + ciphertext_validity_proof, + range_proof, + } => { + if equality_proof.kind != crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality + || ciphertext_validity_proof.kind != crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity + || range_proof.kind != crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU128 + { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "Confidential Burn requires CiphertextCommitmentEquality, BatchedGroupedCiphertext3HandlesValidity, then BatchedRangeProofU128 proof references", + )); + } + for proof in [equality_proof, ciphertext_validity_proof, range_proof] { + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + } + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let new_balance = match new_decryptable_available_balance.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_decryptable_balance", + error, + )); + }, + }; + let auditor_ciphertext_lo = match burn_amount_auditor_ciphertext_lo.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let auditor_ciphertext_hi = match burn_amount_auditor_ciphertext_hi.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let equality_data = ::zeroed(); + let validity_data = ::zeroed(); + let range_data = ::zeroed(); + let equality_context; + let validity_context; + let range_context; + let equality_location = match &equality_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Confidential Burn equality proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &equality_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + equality_context = parse_key!(account, "equality_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&equality_context) + }, + }; + let validity_location = match &ciphertext_validity_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Confidential Burn ciphertext-validity proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &validity_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + validity_context = + parse_key!(account, "ciphertext_validity_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&validity_context) + }, + }; + let range_location = match &range_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Confidential Burn range proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &range_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + range_context = parse_key!(account, "range_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&range_context) + }, + }; + official_instruction( + spl_token_2022_interface::extension::confidential_mint_burn::instruction::inner_confidential_burn( + program_id, + &source, + &mint, + &new_balance, + &auditor_ciphertext_lo, + &auditor_ciphertext_hi, + &authority.authority, + signer_refs.as_slice(), + equality_location, + validity_location, + range_location, + ), + ) + }, + crate::ExSplTokenSingleOperation::PermissionedConfidentialBurn { + source, + mint, + permissioned_burn_authority, + new_decryptable_available_balance, + burn_amount_auditor_ciphertext_lo, + burn_amount_auditor_ciphertext_hi, + authority, + equality_proof, + ciphertext_validity_proof, + range_proof, + } => { + if equality_proof.kind != crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality + || ciphertext_validity_proof.kind != crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity + || range_proof.kind != crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU128 + { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_kind_invalid", + "Permissioned Confidential Burn requires CiphertextCommitmentEquality, BatchedGroupedCiphertext3HandlesValidity, then BatchedRangeProofU128 proof references", + )); + } + for proof in [equality_proof, ciphertext_validity_proof, range_proof] { + match proof.location.validate() { + Ok(()) => {}, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_location_invalid", + error, + )); + }, + } + } + let source = parse_key!(source, "source"); + let mint = parse_key!(mint, "mint"); + let permissioned_burn_authority = + parse_key!(permissioned_burn_authority, "permissioned_burn_authority"); + let new_balance = match new_decryptable_available_balance.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_invalid_decryptable_balance", + error, + )); + }, + }; + let auditor_ciphertext_lo = match burn_amount_auditor_ciphertext_lo.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let auditor_ciphertext_hi = match burn_amount_auditor_ciphertext_hi.parse() { + Ok(value) => value, + Err(error) => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_ciphertext_invalid", + error, + )); + }, + }; + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let equality_data = ::zeroed(); + let validity_data = ::zeroed(); + let range_data = ::zeroed(); + let equality_context; + let validity_context; + let range_context; + let equality_location = match &equality_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Permissioned Confidential Burn equality proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &equality_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + equality_context = parse_key!(account, "equality_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&equality_context) + }, + }; + let validity_location = match &ciphertext_validity_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Permissioned Confidential Burn validity proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &validity_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + validity_context = + parse_key!(account, "ciphertext_validity_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&validity_context) + }, + }; + let range_location = match &range_proof.location { + crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset } => { + let offset = match std::num::NonZeroI8::new(*offset) { + Some(value) => value, + None => { + return Err(kb_core::Error::new( + "execution_spl_token_2022_confidential_proof_offset_invalid", + "Permissioned Confidential Burn range proof offset must be non-zero", + )); + }, + }; + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::InstructionOffset(offset, &range_data) + }, + crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account } => { + range_context = parse_key!(account, "range_proof_context_state_account"); + spl_token_confidential_transfer_proof_extraction::instruction::ProofLocation::ContextStateAccount(&range_context) + }, + }; + let instructions = match spl_token_2022_interface::extension::permissioned_burn::instruction::confidential_burn_with_split_proofs( + program_id, + &source, + &mint, + &permissioned_burn_authority, + &new_balance, + &auditor_ciphertext_lo, + &auditor_ciphertext_hi, + &authority.authority, + signer_refs.as_slice(), + equality_location, + validity_location, + range_location, + ) { + Ok(value) => value, + Err(error) => return Err(kb_core::Error::new( + "execution_spl_token_2022_official_builder_failed", + error.to_string(), + )), + }; + match instructions.into_iter().next() { + Some(value) => Ok(value), + None => Err(kb_core::Error::new( + "execution_spl_token_2022_official_builder_empty", + "official permissioned confidential burn builder returned no instruction", + )), + } + }, + crate::ExSplTokenSingleOperation::UnwrapLamports { + account, + destination, + authority, + amount_lamports, + } => { + let account = parse_key!(account, "account"); + let destination = parse_key!(destination, "destination"); + let authority = parse_token_authority!(authority); + let signer_refs = authority.signers.iter().collect::>(); + let amount_lamports = match amount_lamports { + std::option::Option::Some(value) => { + std::option::Option::Some(parse_raw_amount!(value, "amount_lamports")) + }, + std::option::Option::None => std::option::Option::None, + }; + official_instruction(spl_token_2022_interface::instruction::unwrap_lamports( + program_id, + &account, + &destination, + &authority.authority, + signer_refs.as_slice(), + amount_lamports, + )) + }, + }; +} + +fn build_batch( + _program_id: &solana_pubkey::Pubkey, + _instructions: &[crate::ExSplTokenSingleOperation], +) -> kb_core::Result { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_batch_builder_unavailable", + "Token-2022 Batch is decode-only because spl-token-2022-interface 3.1.1 publishes no official Batch builder", + )); +} + +fn official_instruction( + result: std::result::Result, +) -> kb_core::Result +where + BuilderError: std::fmt::Display, +{ + return match result { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_official_builder_failed", + error.to_string(), + )), + }; +} + +fn parse_pubkey(pubkey: &crate::MdPubkey, field: &str) -> kb_core::Result { + if pubkey.0.trim().is_empty() { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_pubkey_empty", + format!("SPL Token {field} public key must not be empty"), + )); + } + return match solana_pubkey::Pubkey::from_str(pubkey.0.as_str()) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_pubkey_invalid", + format!("invalid SPL Token {field} public key: {error}"), + )), + }; +} + +fn parse_amount(amount: &crate::ExSplTokenAmount, field: &str) -> kb_core::Result { + if amount.0.is_empty() || !amount.0.bytes().all(|value| return value.is_ascii_digit()) { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_amount_invalid", + format!("SPL Token {field} must be an unsigned decimal u64 string"), + )); + } + return match amount.0.parse::() { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_amount_invalid", + format!("invalid SPL Token {field}: {error}"), + )), + }; +} + +fn parse_authority(authority: &crate::ExSplTokenAuthority) -> kb_core::Result { + if authority.multisig_signers.len() > crate::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_multisig_signer_limit_exceeded", + format!( + "SPL Token multisig signer occurrence count {} exceeds {}", + authority.multisig_signers.len(), + crate::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS + ), + )); + } + let parsed_authority = match parse_pubkey(&authority.authority, "authority") { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + let mut signers = std::vec::Vec::with_capacity(authority.multisig_signers.len()); + for signer in &authority.multisig_signers { + let signer = match parse_pubkey(signer, "multisig_signer") { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + signers.push(signer); + } + return std::result::Result::Ok(ParsedAuthority { authority: parsed_authority, signers }); +} + +fn parse_transfer_fee_sources( + sources: &[crate::MdPubkey], +) -> kb_core::Result> { + if sources.is_empty() { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_transfer_fee_sources_empty", + "transfer-fee source account list must not be empty", + )); + } + if sources.len() > crate::EX_SPL_TOKEN2022_MAX_TRANSFER_FEE_SOURCE_ACCOUNTS { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_transfer_fee_source_limit_exceeded", + format!( + "transfer-fee source account count {} exceeds {}", + sources.len(), + crate::EX_SPL_TOKEN2022_MAX_TRANSFER_FEE_SOURCE_ACCOUNTS + ), + )); + } + let mut parsed = std::vec::Vec::with_capacity(sources.len()); + let mut unique = std::collections::BTreeSet::new(); + for source in sources { + let source = match parse_pubkey(source, "transfer_fee_source") { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + if !unique.insert(source) { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_transfer_fee_source_duplicate", + "transfer-fee source accounts must be unique", + )); + } + parsed.push(source); + } + return std::result::Result::Ok(parsed); +} + +fn declared_spend_lamports(operation: &crate::ExSplToken2022Operation) -> kb_core::Result { + return match operation { + crate::ExSplToken2022Operation::Instruction { value } => single_spend_lamports(value), + crate::ExSplToken2022Operation::Batch { instructions } => { + let mut total = 0_u64; + for instruction in instructions { + let amount = match single_spend_lamports(instruction) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + total = match total.checked_add(amount) { + std::option::Option::Some(value) => value, + std::option::Option::None => { + return std::result::Result::Err(kb_core::Error::new( + "execution_spl_token_2022_lamport_spend_overflow", + "SPL Token Batch declared lamport spend exceeds u64", + )); + }, + }; + } + std::result::Result::Ok(total) + }, + }; +} + +fn single_spend_lamports(operation: &crate::ExSplTokenSingleOperation) -> kb_core::Result { + return match operation { + crate::ExSplTokenSingleOperation::UnwrapLamports { + amount_lamports: std::option::Option::Some(value), + .. + } => parse_amount(value, "amount_lamports"), + _ => std::result::Result::Ok(0), + }; +} + +fn has_unbounded_lamport_movement(operation: &crate::ExSplToken2022Operation) -> bool { + return match operation { + crate::ExSplToken2022Operation::Instruction { value } => { + single_has_unbounded_lamport_movement(value) + }, + crate::ExSplToken2022Operation::Batch { instructions } => { + instructions.iter().any(single_has_unbounded_lamport_movement) + }, + }; +} + +fn single_has_unbounded_lamport_movement(operation: &crate::ExSplTokenSingleOperation) -> bool { + return matches!( + operation, + crate::ExSplTokenSingleOperation::WithdrawExcessLamports { .. } + | crate::ExSplTokenSingleOperation::UnwrapLamports { + amount_lamports: std::option::Option::None, + .. + } + ); +} + +fn planned_instruction( + operation_code: &str, + instruction: &solana_instruction::Instruction, +) -> crate::ExApiPlannedInstruction { + return crate::ExApiPlannedInstruction { + program_id: crate::MdProgramId(instruction.program_id.to_string()), + operation_code: std::string::String::from(operation_code), + accounts: instruction + .accounts + .iter() + .map(|account| { + return crate::ExApiPlannedAccount { + pubkey: crate::MdPubkey(account.pubkey.to_string()), + is_signer: account.is_signer, + is_writable: account.is_writable, + }; + }) + .collect(), + data: instruction.data.clone(), + }; +} + +fn required_signers( + fee_payer: &crate::MdPubkey, + accounts: &[solana_instruction::AccountMeta], +) -> std::vec::Vec { + let mut required = vec![crate::ExApiRequiredSigner { + pubkey: fee_payer.clone(), + role: std::string::String::from("fee_payer"), + }]; + for account in accounts { + if !account.is_signer { + continue; + } + let pubkey = crate::MdPubkey(account.pubkey.to_string()); + if required.iter().any(|value| return value.pubkey == pubkey) { + continue; + } + required.push(crate::ExApiRequiredSigner { + pubkey, + role: std::string::String::from("token_authority_or_multisig_signer"), + }); + } + return required; +} + +#[cfg(test)] +pub(crate) mod tests { + fn pubkey(value: &str) -> crate::MdPubkey { + return crate::MdPubkey(std::string::String::from(value)); + } + + fn policy(signers: &[&str], materialization_required: bool) -> crate::ExApiExecutionPolicy { + return crate::ExApiExecutionPolicy { + cost_limit: crate::ExApiExecutionCostLimit { + max_spend_lamports: std::option::Option::Some(u64::MAX), + max_fee_lamports: std::option::Option::Some(10_000), + max_compute_unit_price_micro_lamports: std::option::Option::None, + }, + authorized_signers: signers.iter().map(|value| return pubkey(value)).collect(), + post_execution_validation: crate::ExApiPostExecutionValidationPolicy { + canonical_insert_required: true, + core_extraction_required: true, + decode_replay_required: true, + materialization_required, + }, + ..crate::ExApiExecutionPolicy::default() + }; + } + + pub(crate) fn intent( + operation: crate::ExSplToken2022Operation, + ) -> crate::ExSplToken2022ExecutionIntent { + let fee_payer = kb_program_ids::SYSTEM_PROGRAM_ID; + return crate::ExSplToken2022ExecutionIntent { + intent_id: std::string::String::from("token-intent-1"), + fee_payer: pubkey(fee_payer), + policy: policy( + &[fee_payer, kb_program_ids::VOTE_PROGRAM_ID, kb_program_ids::STAKE_PROGRAM_ID], + operation.requires_materialization(), + ), + operation, + }; + } + + fn authority(signers: &[&str]) -> crate::ExSplTokenAuthority { + return crate::ExSplTokenAuthority { + authority: pubkey(kb_program_ids::CONFIG_PROGRAM_ID), + multisig_signers: signers.iter().map(|value| return pubkey(value)).collect(), + }; + } + + fn planned_single_instruction( + operation: crate::ExSplTokenSingleOperation, + ) -> crate::ExApiPlannedInstruction { + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("single instruction plan failed: {error}")); + return plan + .instructions + .into_iter() + .next() + .unwrap_or_else(|| panic!("single instruction plan must contain one instruction")); + } + + fn transfer_checked() -> crate::ExSplTokenSingleOperation { + return crate::ExSplTokenSingleOperation::TransferChecked { + source: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + mint: pubkey(kb_program_ids::CONFIG_PROGRAM_ID), + destination: pubkey(kb_program_ids::STAKE_PROGRAM_ID), + authority: authority(&[kb_program_ids::VOTE_PROGRAM_ID]), + amount: crate::ExSplTokenAmount(std::string::String::from("18446744073709551615")), + decimals: 9, + }; + } + + fn all_single_operations() -> std::vec::Vec<(u8, crate::ExSplTokenSingleOperation)> { + let first = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let second = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let third = pubkey(kb_program_ids::STAKE_PROGRAM_ID); + let sauthority = authority(&[]); + let amount = crate::ExSplTokenAmount(std::string::String::from("42")); + return vec![ + ( + 20, + crate::ExSplTokenSingleOperation::InitializeMint { + mint: first.clone(), + mint_authority: second.clone(), + freeze_authority: std::option::Option::Some(third.clone()), + decimals: 9, + }, + ), + ( + 18, + crate::ExSplTokenSingleOperation::InitializeAccount { + account: first.clone(), + mint: second.clone(), + owner: third.clone(), + }, + ), + ( + 19, + crate::ExSplTokenSingleOperation::InitializeMultisig { + multisig: first.clone(), + members: vec![second.clone(), third.clone()], + threshold: 1, + }, + ), + ( + 3, + crate::ExSplTokenSingleOperation::Transfer { + source: first.clone(), + destination: second.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + }, + ), + ( + 4, + crate::ExSplTokenSingleOperation::Approve { + source: first.clone(), + delegate: second.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + }, + ), + ( + 5, + crate::ExSplTokenSingleOperation::Revoke { + source: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 6, + crate::ExSplTokenSingleOperation::SetAuthority { + owned: first.clone(), + authority_type: crate::ExSplTokenAuthorityType::CloseAccount, + new_authority: std::option::Option::Some(second.clone()), + current_authority: sauthority.clone(), + }, + ), + ( + 7, + crate::ExSplTokenSingleOperation::MintTo { + mint: first.clone(), + destination: second.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + }, + ), + ( + 8, + crate::ExSplTokenSingleOperation::Burn { + source: first.clone(), + mint: second.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + }, + ), + ( + 9, + crate::ExSplTokenSingleOperation::CloseAccount { + account: first.clone(), + destination: second.clone(), + authority: sauthority.clone(), + }, + ), + ( + 10, + crate::ExSplTokenSingleOperation::FreezeAccount { + account: first.clone(), + mint: second.clone(), + authority: sauthority.clone(), + }, + ), + ( + 11, + crate::ExSplTokenSingleOperation::ThawAccount { + account: first.clone(), + mint: second.clone(), + authority: sauthority.clone(), + }, + ), + (12, transfer_checked()), + ( + 13, + crate::ExSplTokenSingleOperation::ApproveChecked { + source: first.clone(), + mint: second.clone(), + delegate: third.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + decimals: 9, + }, + ), + ( + 14, + crate::ExSplTokenSingleOperation::MintToChecked { + mint: first.clone(), + destination: second.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + decimals: 9, + }, + ), + ( + 15, + crate::ExSplTokenSingleOperation::BurnChecked { + source: first.clone(), + mint: second.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + decimals: 9, + }, + ), + ( + 17, + crate::ExSplTokenSingleOperation::SyncNative { + account: first.clone(), + include_rent_sysvar: true, + }, + ), + (21, crate::ExSplTokenSingleOperation::GetAccountDataSize { mint: first.clone() }), + ( + 22, + crate::ExSplTokenSingleOperation::InitializeImmutableOwner { account: first.clone() }, + ), + ( + 23, + crate::ExSplTokenSingleOperation::AmountToUiAmount { + mint: first.clone(), + amount: amount.clone(), + }, + ), + ( + 24, + crate::ExSplTokenSingleOperation::UiAmountToAmount { + mint: first.clone(), + ui_amount: std::string::String::from("0.000000042"), + }, + ), + ( + 29, + crate::ExSplTokenSingleOperation::Reallocate { + account: first.clone(), + payer: second.clone(), + authority: sauthority.clone(), + extension_types: vec![9, 10, 12], + }, + ), + ( + 32, + crate::ExSplTokenSingleOperation::InitializeNonTransferableMint { + mint: first.clone(), + }, + ), + ( + 35, + crate::ExSplTokenSingleOperation::InitializePermanentDelegate { + mint: first.clone(), + delegate: second.clone(), + }, + ), + ( + 33, + crate::ExSplTokenSingleOperation::InitializeInterestBearingMint { + mint: first.clone(), + rate_authority: std::option::Option::Some(second.clone()), + rate_basis_points: -125, + }, + ), + ( + 33, + crate::ExSplTokenSingleOperation::UpdateInterestBearingRate { + mint: first.clone(), + authority: sauthority.clone(), + rate_basis_points: 250, + }, + ), + ( + 38, + crate::ExSplTokenSingleOperation::WithdrawExcessLamports { + account: first.clone(), + destination: second.clone(), + authority: sauthority.clone(), + }, + ), + ( + 26, + crate::ExSplTokenSingleOperation::InitializeTransferFeeConfig { + mint: first.clone(), + transfer_fee_config_authority: std::option::Option::Some(second.clone()), + withdraw_withheld_authority: std::option::Option::Some(third.clone()), + transfer_fee_basis_points: 250, + maximum_fee: amount.clone(), + }, + ), + ( + 26, + crate::ExSplTokenSingleOperation::SetTransferFee { + mint: first.clone(), + authority: sauthority.clone(), + transfer_fee_basis_points: 500, + maximum_fee: amount.clone(), + }, + ), + ( + 26, + crate::ExSplTokenSingleOperation::TransferCheckedWithFee { + source: first.clone(), + mint: second.clone(), + destination: third.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + decimals: 9, + fee: crate::ExSplTokenAmount(std::string::String::from("1")), + }, + ), + ( + 26, + crate::ExSplTokenSingleOperation::WithdrawWithheldTokensFromMint { + mint: first.clone(), + destination: second.clone(), + authority: sauthority.clone(), + }, + ), + ( + 26, + crate::ExSplTokenSingleOperation::WithdrawWithheldTokensFromAccounts { + mint: first.clone(), + destination: second.clone(), + authority: sauthority.clone(), + sources: vec![third.clone()], + }, + ), + ( + 26, + crate::ExSplTokenSingleOperation::HarvestWithheldTokensToMint { + mint: first.clone(), + sources: vec![third.clone()], + }, + ), + ( + 28, + crate::ExSplTokenSingleOperation::InitializeDefaultAccountState { + mint: first.clone(), + state: crate::ExSplTokenDefaultAccountState::Frozen, + }, + ), + ( + 28, + crate::ExSplTokenSingleOperation::UpdateDefaultAccountState { + mint: first.clone(), + authority: sauthority.clone(), + state: crate::ExSplTokenDefaultAccountState::Initialized, + }, + ), + ( + 30, + crate::ExSplTokenSingleOperation::EnableRequiredTransferMemos { + account: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 30, + crate::ExSplTokenSingleOperation::DisableRequiredTransferMemos { + account: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 34, + crate::ExSplTokenSingleOperation::EnableCpiGuard { + account: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 34, + crate::ExSplTokenSingleOperation::DisableCpiGuard { + account: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 36, + crate::ExSplTokenSingleOperation::InitializeTransferHook { + mint: first.clone(), + authority: std::option::Option::Some(second.clone()), + program_id: std::option::Option::Some(third.clone()), + }, + ), + ( + 36, + crate::ExSplTokenSingleOperation::UpdateTransferHook { + mint: first.clone(), + authority: sauthority.clone(), + program_id: std::option::Option::None, + }, + ), + ( + 39, + crate::ExSplTokenSingleOperation::InitializeMetadataPointer { + mint: first.clone(), + authority: std::option::Option::Some(second.clone()), + metadata_address: std::option::Option::Some(third.clone()), + }, + ), + ( + 39, + crate::ExSplTokenSingleOperation::UpdateMetadataPointer { + mint: first.clone(), + authority: sauthority.clone(), + metadata_address: std::option::Option::None, + }, + ), + ( + 40, + crate::ExSplTokenSingleOperation::InitializeGroupPointer { + mint: first.clone(), + authority: std::option::Option::Some(second.clone()), + group_address: std::option::Option::Some(third.clone()), + }, + ), + ( + 40, + crate::ExSplTokenSingleOperation::UpdateGroupPointer { + mint: first.clone(), + authority: sauthority.clone(), + group_address: std::option::Option::None, + }, + ), + ( + 41, + crate::ExSplTokenSingleOperation::InitializeGroupMemberPointer { + mint: first.clone(), + authority: std::option::Option::Some(second.clone()), + member_address: std::option::Option::Some(third.clone()), + }, + ), + ( + 41, + crate::ExSplTokenSingleOperation::UpdateGroupMemberPointer { + mint: first.clone(), + authority: sauthority.clone(), + member_address: std::option::Option::None, + }, + ), + ( + 255, + crate::ExSplTokenSingleOperation::InitializeTokenMetadata { + metadata: first.clone(), + update_authority: second.clone(), + mint: first.clone(), + mint_authority: third.clone(), + name: std::string::String::from("Token"), + symbol: std::string::String::from("TKN"), + uri: std::string::String::from("https://example.invalid/token.json"), + }, + ), + ( + 255, + crate::ExSplTokenSingleOperation::UpdateTokenMetadataField { + metadata: first.clone(), + update_authority: second.clone(), + field: crate::ExSplTokenMetadataField::Uri, + value: std::string::String::from("https://example.invalid/updated.json"), + }, + ), + ( + 255, + crate::ExSplTokenSingleOperation::RemoveTokenMetadataKey { + metadata: first.clone(), + update_authority: second.clone(), + key: std::string::String::from("website"), + idempotent: true, + }, + ), + ( + 255, + crate::ExSplTokenSingleOperation::InitializeTokenGroup { + group: first.clone(), + mint: first.clone(), + mint_authority: second.clone(), + update_authority: std::option::Option::Some(third.clone()), + max_size: 42, + }, + ), + ( + 255, + crate::ExSplTokenSingleOperation::UpdateTokenGroupMaxSize { + group: first.clone(), + update_authority: second.clone(), + max_size: 84, + }, + ), + ( + 255, + crate::ExSplTokenSingleOperation::InitializeTokenGroupMember { + member: first.clone(), + member_mint: first.clone(), + member_mint_authority: second.clone(), + group: third.clone(), + group_update_authority: second.clone(), + }, + ), + ( + 43, + crate::ExSplTokenSingleOperation::InitializeScaledUiAmount { + mint: first.clone(), + authority: std::option::Option::Some(second.clone()), + multiplier: crate::ExSplTokenMultiplier(std::string::String::from("1.5")), + }, + ), + ( + 43, + crate::ExSplTokenSingleOperation::UpdateScaledUiAmountMultiplier { + mint: first.clone(), + authority: sauthority.clone(), + multiplier: crate::ExSplTokenMultiplier(std::string::String::from("2.0")), + effective_timestamp: 1_900_000_000, + }, + ), + ( + 44, + crate::ExSplTokenSingleOperation::InitializePausableConfig { + mint: first.clone(), + authority: second.clone(), + }, + ), + ( + 44, + crate::ExSplTokenSingleOperation::Pause { + mint: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 44, + crate::ExSplTokenSingleOperation::Resume { + mint: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 46, + crate::ExSplTokenSingleOperation::InitializePermissionedBurn { + mint: first.clone(), + authority: second.clone(), + }, + ), + ( + 46, + crate::ExSplTokenSingleOperation::PermissionedBurn { + source: first.clone(), + mint: second.clone(), + permissioned_burn_authority: third.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + }, + ), + ( + 46, + crate::ExSplTokenSingleOperation::PermissionedBurnChecked { + source: first.clone(), + mint: second.clone(), + permissioned_burn_authority: third.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + decimals: 9, + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::InitializeConfidentialTransferMint { + mint: first.clone(), + authority: Some(second.clone()), + auto_approve_new_accounts: true, + auditor_elgamal_pubkey: Some(crate::ExSplTokenElGamalPubkey("11".repeat(32))), + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::UpdateConfidentialTransferMint { + mint: first.clone(), + authority: sauthority.clone(), + auto_approve_new_accounts: false, + auditor_elgamal_pubkey: None, + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::ApplyPendingConfidentialBalance { + account: first.clone(), + expected_pending_balance_credit_counter: u64::MAX, + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("22".repeat(36)), + authority: sauthority.clone(), + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::ApproveConfidentialTransferAccount { + account: first.clone(), + mint: second.clone(), + authority: sauthority.clone(), + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::DepositConfidentialTokens { + account: first.clone(), + mint: second.clone(), + authority: sauthority.clone(), + amount: amount.clone(), + decimals: 9, + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::EnableConfidentialCredits { + account: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::DisableConfidentialCredits { + account: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::EnableNonConfidentialCredits { + account: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::DisableNonConfidentialCredits { + account: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::ConfigureConfidentialTransferAccount { + account: first.clone(), + mint: second.clone(), + decryptable_zero_balance: crate::ExSplTokenDecryptableBalance("33".repeat(36)), + maximum_pending_balance_credit_counter: u64::MAX, + authority: sauthority.clone(), + proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::PubkeyValidity, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { + account: third.clone(), + }, + }, + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::ConfigureConfidentialTransferAccountWithRegistry { + account: first.clone(), + mint: second.clone(), + registry_account: third.clone(), + payer: None, + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::EmptyConfidentialTransferAccount { + account: first.clone(), + authority: sauthority.clone(), + proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::ZeroCiphertext, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { + account: third.clone(), + }, + }, + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::WithdrawConfidentialTokens { + account: first.clone(), + mint: second.clone(), + amount: amount.clone(), + decimals: 9, + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("44".repeat(36)), + authority: sauthority.clone(), + equality_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account: third.clone() }, + }, + range_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU64, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: 1 }, + }, + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::TransferConfidentialTokens { + source: first.clone(), + mint: second.clone(), + destination: third.clone(), + new_source_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("55".repeat(36)), + transfer_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext("66".repeat(64)), + transfer_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext("77".repeat(64)), + authority: sauthority.clone(), + equality_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account: third.clone() }, + }, + ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: 1 }, + }, + range_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU128, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: 2 }, + }, + }, + ), + ( + 27, + crate::ExSplTokenSingleOperation::TransferConfidentialTokensWithFee { + source: first.clone(), + mint: second.clone(), + destination: third.clone(), + new_source_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("00".repeat(36)), + transfer_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext("00".repeat(64)), + transfer_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext("00".repeat(64)), + authority: sauthority.clone(), + equality_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -1 }, + }, + transfer_amount_ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -2 }, + }, + fee_sigma_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::PercentageWithFee, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -3 }, + }, + fee_ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext2HandlesValidity, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -4 }, + }, + range_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU256, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -5 }, + }, + }, + ), + ( + 37, + crate::ExSplTokenSingleOperation::InitializeConfidentialTransferFeeConfig { + mint: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + authority: Some(pubkey(kb_program_ids::CONFIG_PROGRAM_ID)), + withdraw_withheld_authority_elgamal_pubkey: crate::ExSplTokenElGamalPubkey("11".repeat(32)), + }, + ), + ( + 37, + crate::ExSplTokenSingleOperation::EnableConfidentialTransferFeeHarvest { + mint: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + authority: authority(&[]), + }, + ), + ( + 37, + crate::ExSplTokenSingleOperation::DisableConfidentialTransferFeeHarvest { + mint: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + authority: authority(&[]), + }, + ), + ( + 37, + crate::ExSplTokenSingleOperation::HarvestConfidentialWithheldTokensToMint { + mint: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + sources: vec![pubkey(kb_program_ids::CONFIG_PROGRAM_ID)], + }, + ), + ( + 37, + crate::ExSplTokenSingleOperation::WithdrawConfidentialWithheldTokensFromMint { + mint: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + destination: pubkey(kb_program_ids::CONFIG_PROGRAM_ID), + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("22".repeat(36)), + authority: authority(&[]), + proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -1 }, + }, + }, + ), + ( + 37, + crate::ExSplTokenSingleOperation::WithdrawConfidentialWithheldTokensFromAccounts { + mint: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + destination: pubkey(kb_program_ids::CONFIG_PROGRAM_ID), + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("33".repeat(36)), + authority: authority(&[]), + sources: vec![pubkey(kb_program_ids::STAKE_PROGRAM_ID)], + proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -1 }, + }, + }, + ), + ( + 42, + crate::ExSplTokenSingleOperation::InitializeConfidentialMintBurnMint { + mint: first.clone(), + supply_elgamal_pubkey: crate::ExSplTokenElGamalPubkey("11".repeat(32)), + decryptable_supply: crate::ExSplTokenDecryptableBalance("22".repeat(36)), + }, + ), + ( + 42, + crate::ExSplTokenSingleOperation::RotateConfidentialSupplyElGamalPubkey { + mint: first.clone(), + new_supply_elgamal_pubkey: crate::ExSplTokenElGamalPubkey("33".repeat(32)), + authority: sauthority.clone(), + proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { + account: third.clone(), + }, + }, + }, + ), + ( + 42, + crate::ExSplTokenSingleOperation::UpdateConfidentialDecryptableSupply { + mint: first.clone(), + new_decryptable_supply: crate::ExSplTokenDecryptableBalance("44".repeat(36)), + authority: sauthority.clone(), + }, + ), + ( + 42, + crate::ExSplTokenSingleOperation::ApplyPendingConfidentialBurn { + mint: first.clone(), + authority: sauthority.clone(), + }, + ), + ( + 42, + crate::ExSplTokenSingleOperation::ConfidentialMint { + destination: first.clone(), + mint: second.clone(), + new_decryptable_supply: crate::ExSplTokenDecryptableBalance("55".repeat(36)), + mint_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext("66".repeat(64)), + mint_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext("77".repeat(64)), + authority: sauthority.clone(), + equality_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -1 }, + }, + ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account: third.clone() }, + }, + range_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU128, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -2 }, + }, + }, + ), + ( + 42, + crate::ExSplTokenSingleOperation::ConfidentialBurn { + source: first.clone(), + mint: second.clone(), + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("88".repeat(36)), + burn_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext("99".repeat(64)), + burn_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext("aa".repeat(64)), + authority: sauthority.clone(), + equality_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account: third.clone() }, + }, + ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -1 }, + }, + range_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU128, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -2 }, + }, + }, + ), + ( + 46, + crate::ExSplTokenSingleOperation::PermissionedConfidentialBurn { + source: first.clone(), + mint: second.clone(), + permissioned_burn_authority: third.clone(), + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("bb".repeat(36)), + burn_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext("cc".repeat(64)), + burn_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext("dd".repeat(64)), + authority: sauthority.clone(), + equality_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account: third.clone() }, + }, + ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account: third.clone() }, + }, + range_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU128, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { account: third.clone() }, + }, + }, + ), + ( + 45, + crate::ExSplTokenSingleOperation::UnwrapLamports { + account: first, + destination: second, + authority: sauthority, + amount_lamports: std::option::Option::Some(amount), + }, + ), + ]; + } + + #[test] + fn empty_confidential_account_preserves_zero_ciphertext_proof_modes_and_authority_metas() { + let account = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let authority_key = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let signer = pubkey(kb_program_ids::STAKE_PROGRAM_ID); + let context = pubkey(kb_program_ids::VOTE_PROGRAM_ID); + for proof in [ + crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::ZeroCiphertext, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { + offset: -1, + }, + }, + crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::ZeroCiphertext, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { + account: context.clone(), + }, + }, + ] { + let operation = crate::ExSplTokenSingleOperation::EmptyConfidentialTransferAccount { + account: account.clone(), + authority: crate::ExSplTokenAuthority { + authority: authority_key.clone(), + multisig_signers: vec![signer.clone()], + }, + proof, + }; + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("empty account plan failed: {error}")); + assert_eq!(plan.instructions.len(), 1); + let instruction = &plan.instructions[0]; + assert_eq!(instruction.data[0], 27); + assert_eq!(instruction.data[1], 4); + assert_eq!(instruction.accounts[0].pubkey, account); + assert!(instruction.accounts[0].is_writable); + assert_eq!(instruction.accounts[2].pubkey, authority_key); + assert!(!instruction.accounts[2].is_signer); + assert_eq!(instruction.accounts[3].pubkey, signer); + assert!(instruction.accounts[3].is_signer); + } + let invalid = crate::ExSplTokenSingleOperation::EmptyConfidentialTransferAccount { + account, + authority: crate::ExSplTokenAuthority { + authority: authority_key, + multisig_signers: vec![], + }, + proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::PubkeyValidity, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { + offset: 1, + }, + }, + }; + let result = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(invalid), + }), + ); + assert!(result.is_err()); + } + + #[test] + fn withdraw_confidential_tokens_preserves_two_proof_modes_wire_and_authority_metas() { + let account = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let mint = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let sauthority = pubkey(kb_program_ids::STAKE_PROGRAM_ID); + let signer = pubkey(kb_program_ids::VOTE_PROGRAM_ID); + let context = pubkey(kb_program_ids::ADDRESS_LOOKUP_TABLE_PROGRAM_ID); + let operation = crate::ExSplTokenSingleOperation::WithdrawConfidentialTokens { + account: account.clone(), + mint: mint.clone(), + amount: crate::ExSplTokenAmount("18446744073709551615".to_owned()), + decimals: 9, + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("55".repeat(36)), + authority: crate::ExSplTokenAuthority { + authority: sauthority.clone(), + multisig_signers: vec![signer.clone()], + }, + equality_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { + account: context.clone(), + }, + }, + range_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU64, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { + offset: -1, + }, + }, + }; + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }), + ) + .unwrap_or_else(|error| panic!("withdraw plan failed: {error}")); + let instruction = &plan.instructions[0]; + assert_eq!(instruction.data[0], 27); + assert_eq!(instruction.data[1], 6); + assert_eq!(instruction.accounts[0].pubkey, account); + assert!(instruction.accounts[0].is_writable); + assert_eq!(instruction.accounts[1].pubkey, mint); + assert!(!instruction.accounts[1].is_writable); + assert_eq!(instruction.accounts[3].pubkey, context); + assert_eq!(instruction.accounts[4].pubkey, sauthority); + assert!(!instruction.accounts[4].is_signer); + assert_eq!(instruction.accounts[5].pubkey, signer); + assert!(instruction.accounts[5].is_signer); + } + + #[test] + fn transfer_confidential_tokens_preserves_three_proof_modes_ciphertexts_and_authority_metas() { + let source = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let mint = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let destination = pubkey(kb_program_ids::STAKE_PROGRAM_ID); + let sauthority = pubkey(kb_program_ids::VOTE_PROGRAM_ID); + let signer = pubkey(kb_program_ids::ADDRESS_LOOKUP_TABLE_PROGRAM_ID); + let equality_context = pubkey(kb_program_ids::COMPUTE_BUDGET_PROGRAM_ID); + let range_context = pubkey(kb_program_ids::BPF_LOADER_UPGRADEABLE_PROGRAM_ID); + let operation = crate::ExSplTokenSingleOperation::TransferConfidentialTokens { + source: source.clone(), + mint: mint.clone(), + destination: destination.clone(), + new_source_decryptable_available_balance: crate::ExSplTokenDecryptableBalance( + "88".repeat(36), + ), + transfer_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext( + "99".repeat(64), + ), + transfer_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext( + "aa".repeat(64), + ), + authority: crate::ExSplTokenAuthority { + authority: sauthority.clone(), + multisig_signers: vec![signer.clone()], + }, + equality_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { + account: equality_context.clone(), + }, + }, + ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference { + kind: + crate::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { + offset: -1, + }, + }, + range_proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::BatchedRangeProofU128, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { + account: range_context.clone(), + }, + }, + }; + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }), + ) + .unwrap_or_else(|error| panic!("confidential transfer plan failed: {error}")); + let instruction = &plan.instructions[0]; + assert_eq!(instruction.data[0], 27); + assert_eq!(instruction.data[1], 7); + assert_eq!(instruction.accounts[0].pubkey, source); + assert!(instruction.accounts[0].is_writable); + assert_eq!(instruction.accounts[1].pubkey, mint); + assert!(!instruction.accounts[1].is_writable); + assert_eq!(instruction.accounts[2].pubkey, destination); + assert!(instruction.accounts[2].is_writable); + assert_eq!(instruction.accounts[4].pubkey, equality_context); + assert_eq!(instruction.accounts[5].pubkey, range_context); + assert_eq!(instruction.accounts[6].pubkey, sauthority); + assert!(!instruction.accounts[6].is_signer); + assert_eq!(instruction.accounts[7].pubkey, signer); + assert!(instruction.accounts[7].is_signer); + } + + #[test] + fn scaled_ui_pausable_and_permissioned_burn_preserve_exact_public_wire_and_metas() { + let operations = all_single_operations(); + for expected_tag in [43u8, 44u8, 46u8] { + let matching = operations + .iter() + .filter(|(tag, _)| return *tag == expected_tag) + .collect::>(); + assert!(!matching.is_empty()); + for (_, operation) in matching { + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation.clone()), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("extension tag {expected_tag} failed: {error}")); + assert_eq!(plan.instructions[0].data[0], expected_tag); + } + } + let invalid = crate::ExSplTokenSingleOperation::InitializeScaledUiAmount { + mint: crate::MdPubkey(std::string::String::from("11111111111111111111111111111111")), + authority: std::option::Option::None, + multiplier: crate::ExSplTokenMultiplier(std::string::String::from("0")), + }; + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(invalid), + }); + let error = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .expect_err("zero multiplier must fail closed"); + assert_eq!(error.code(), "execution_spl_token_2022_multiplier_invalid"); + } + + #[test] + fn confidential_transfer_fee_public_builders_preserve_wire_accounts_and_authorities() { + let mint = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let authority_key = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let signer = pubkey(kb_program_ids::STAKE_PROGRAM_ID); + let source = pubkey(kb_program_ids::VOTE_PROGRAM_ID); + let initialize = planned_single_instruction( + crate::ExSplTokenSingleOperation::InitializeConfidentialTransferFeeConfig { + mint: mint.clone(), + authority: Some(authority_key.clone()), + withdraw_withheld_authority_elgamal_pubkey: crate::ExSplTokenElGamalPubkey( + "11".repeat(32), + ), + }, + ); + assert_eq!(initialize.data[0], 37); + assert_eq!(initialize.data[1], 0); + assert_eq!(initialize.accounts.len(), 1); + assert!(initialize.accounts[0].is_writable); + let multisig = crate::ExSplTokenAuthority { + authority: authority_key.clone(), + multisig_signers: vec![signer.clone()], + }; + let enable = planned_single_instruction( + crate::ExSplTokenSingleOperation::EnableConfidentialTransferFeeHarvest { + mint: mint.clone(), + authority: multisig.clone(), + }, + ); + assert_eq!(&enable.data[..2], &[37, 4]); + assert_eq!(enable.accounts.len(), 3); + assert!(!enable.accounts[1].is_signer); + assert!(enable.accounts[2].is_signer); + let disable = planned_single_instruction( + crate::ExSplTokenSingleOperation::DisableConfidentialTransferFeeHarvest { + mint: mint.clone(), + authority: multisig, + }, + ); + assert_eq!(&disable.data[..2], &[37, 5]); + let harvest = planned_single_instruction( + crate::ExSplTokenSingleOperation::HarvestConfidentialWithheldTokensToMint { + mint, + sources: vec![source], + }, + ); + assert_eq!(&harvest.data[..2], &[37, 3]); + assert_eq!(harvest.accounts.len(), 2); + assert!(harvest.accounts.iter().all(|meta| return meta.is_writable)); + } + + #[test] + fn confidential_fee_withdraw_from_mint_preserves_equality_proof_modes_and_authority_metas() { + let mint = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let destination = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let sauthority = pubkey(kb_program_ids::STAKE_PROGRAM_ID); + let signer = pubkey(kb_program_ids::VOTE_PROGRAM_ID); + let context = pubkey(kb_program_ids::ADDRESS_LOOKUP_TABLE_PROGRAM_ID); + for proof in [ + crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { + offset: -1, + }, + }, + crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality, + location: crate::ExSplTokenConfidentialProofLocation::ContextStateAccount { + account: context.clone(), + }, + }, + ] { + let instruction = planned_single_instruction( + crate::ExSplTokenSingleOperation::WithdrawConfidentialWithheldTokensFromMint { + mint: mint.clone(), + destination: destination.clone(), + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance( + "33".repeat(36), + ), + authority: crate::ExSplTokenAuthority { + authority: sauthority.clone(), + multisig_signers: vec![signer.clone()], + }, + proof, + }, + ); + assert_eq!(&instruction.data[..2], &[37, 1]); + assert_eq!(instruction.accounts[0].pubkey, mint); + assert!(instruction.accounts[0].is_writable); + assert_eq!(instruction.accounts[1].pubkey, destination); + assert!(instruction.accounts[1].is_writable); + assert_eq!(instruction.accounts[3].pubkey, sauthority); + assert!(!instruction.accounts[3].is_signer); + assert_eq!(instruction.accounts[4].pubkey, signer); + assert!(instruction.accounts[4].is_signer); + } + let invalid = + crate::ExSplTokenSingleOperation::WithdrawConfidentialWithheldTokensFromMint { + mint, + destination, + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance( + "44".repeat(36), + ), + authority: crate::ExSplTokenAuthority { + authority: sauthority, + multisig_signers: vec![signer], + }, + proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { + offset: -1, + }, + }, + }; + let error = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(invalid), + }), + ) + .expect_err("wrong confidential fee proof kind must fail closed"); + assert_eq!(error.code(), "execution_spl_token_2022_confidential_proof_kind_invalid"); + } + + #[test] + fn confidential_fee_withdraw_from_accounts_preserves_sources_proof_and_multisig_order() { + let mint = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let destination = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let sauthority = pubkey(kb_program_ids::STAKE_PROGRAM_ID); + let signer = pubkey(kb_program_ids::VOTE_PROGRAM_ID); + let first_source = pubkey(kb_program_ids::ADDRESS_LOOKUP_TABLE_PROGRAM_ID); + let second_source = pubkey(kb_program_ids::COMPUTE_BUDGET_PROGRAM_ID); + let instruction = planned_single_instruction( + crate::ExSplTokenSingleOperation::WithdrawConfidentialWithheldTokensFromAccounts { + mint: mint.clone(), + destination: destination.clone(), + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance( + "55".repeat(36), + ), + authority: crate::ExSplTokenAuthority { + authority: sauthority.clone(), + multisig_signers: vec![signer.clone()], + }, + sources: vec![first_source.clone(), second_source.clone()], + proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { + offset: -1, + }, + }, + }, + ); + assert_eq!(&instruction.data[..2], &[37, 2]); + assert_eq!(instruction.data[2], 2); + assert_eq!(instruction.data[3] as i8, -1); + assert_eq!(instruction.accounts[0].pubkey, mint); + assert!(instruction.accounts[0].is_writable); + assert_eq!(instruction.accounts[1].pubkey, destination); + assert!(instruction.accounts[1].is_writable); + assert_eq!(instruction.accounts[3].pubkey, sauthority); + assert!(!instruction.accounts[3].is_signer); + assert_eq!(instruction.accounts[4].pubkey, signer); + assert!(instruction.accounts[4].is_signer); + assert_eq!(instruction.accounts[5].pubkey, first_source); + assert!(instruction.accounts[5].is_writable); + assert_eq!(instruction.accounts[6].pubkey, second_source); + assert!(instruction.accounts[6].is_writable); + let duplicate_error = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new( + crate::ExSplTokenSingleOperation::WithdrawConfidentialWithheldTokensFromAccounts { + mint, + destination, + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance("66".repeat(36)), + authority: crate::ExSplTokenAuthority { + authority: sauthority, + multisig_signers: vec![signer], + }, + sources: vec![first_source.clone(), first_source], + proof: crate::ExSplTokenConfidentialProofReference { + kind: crate::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality, + location: crate::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: -1 }, + }, + }, + ), + }), + ) + .expect_err("duplicate confidential fee source must fail closed"); + assert_eq!( + duplicate_error.code(), + "execution_spl_token_2022_transfer_fee_source_duplicate" + ); + } + + #[test] + fn every_current_or_recent_single_operation_uses_its_published_tag() { + let operations = all_single_operations(); + assert_eq!(operations.len(), crate::EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES.len()); + for (tag, operation) in operations { + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("tag {tag} plan failed: {error}")); + if tag == 255 { + assert!(plan.instructions[0].data.len() >= 8); + } else { + assert_eq!(plan.instructions[0].data[0], tag); + } + } + } + + #[test] + fn checked_transfer_matches_official_builder_and_preserves_u64_max() { + let operation = transfer_checked(); + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("checked transfer plan failed: {error}")); + assert_eq!(plan.instructions.len(), 1); + assert_eq!(plan.instructions[0].data[0], 12); + assert_eq!(&plan.instructions[0].data[1..9], &u64::MAX.to_le_bytes()); + assert_eq!(plan.instructions[0].data[9], 9); + assert_eq!(plan.required_signers.len(), 2); + } + + #[test] + fn multisig_meta_order_is_preserved_while_transaction_signers_are_unique() { + let first = kb_program_ids::VOTE_PROGRAM_ID; + let second = kb_program_ids::STAKE_PROGRAM_ID; + let operation = crate::ExSplTokenSingleOperation::Transfer { + source: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + destination: pubkey(kb_program_ids::CONFIG_PROGRAM_ID), + authority: authority(&[first, second, first]), + amount: crate::ExSplTokenAmount(std::string::String::from("1")), + }; + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("multisig transfer plan failed: {error}")); + let accounts = &plan.instructions[0].accounts; + assert_eq!(accounts[3].pubkey.0, first); + assert_eq!(accounts[4].pubkey.0, second); + assert_eq!(accounts[5].pubkey.0, first); + assert_eq!(plan.required_signers.len(), 3); + } + + #[test] + fn default_state_memo_and_cpi_guard_builders_preserve_exact_wire_and_authority_metas() { + let first = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let sauthority = + authority(&[kb_program_ids::VOTE_PROGRAM_ID, kb_program_ids::STAKE_PROGRAM_ID]); + let cases = [ + ( + crate::ExSplTokenSingleOperation::InitializeDefaultAccountState { + mint: first.clone(), + state: crate::ExSplTokenDefaultAccountState::Frozen, + }, + 28_u8, + 0_u8, + 1_usize, + ), + ( + crate::ExSplTokenSingleOperation::UpdateDefaultAccountState { + mint: first.clone(), + authority: sauthority.clone(), + state: crate::ExSplTokenDefaultAccountState::Initialized, + }, + 28_u8, + 1_u8, + 4_usize, + ), + ( + crate::ExSplTokenSingleOperation::EnableRequiredTransferMemos { + account: first.clone(), + authority: sauthority.clone(), + }, + 30_u8, + 0_u8, + 4_usize, + ), + ( + crate::ExSplTokenSingleOperation::DisableRequiredTransferMemos { + account: first.clone(), + authority: sauthority.clone(), + }, + 30_u8, + 1_u8, + 4_usize, + ), + ( + crate::ExSplTokenSingleOperation::EnableCpiGuard { + account: first.clone(), + authority: sauthority.clone(), + }, + 34_u8, + 0_u8, + 4_usize, + ), + ( + crate::ExSplTokenSingleOperation::DisableCpiGuard { + account: first, + authority: sauthority, + }, + 34_u8, + 1_u8, + 4_usize, + ), + ]; + for (operation, outer_tag, sub_tag, account_count) in cases { + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("extension plan failed: {error}")); + assert_eq!(plan.instructions[0].data[0], outer_tag); + assert_eq!(plan.instructions[0].data[1], sub_tag); + assert_eq!(plan.instructions[0].accounts.len(), account_count); + assert!(plan.instructions[0].accounts[0].is_writable); + } + } + + #[test] + fn hook_and_pointer_builders_preserve_exact_wire_optional_values_and_authority_metas() { + let mint = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let target = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let sauthority = + authority(&[kb_program_ids::VOTE_PROGRAM_ID, kb_program_ids::STAKE_PROGRAM_ID]); + let cases = [ + ( + crate::ExSplTokenSingleOperation::InitializeTransferHook { + mint: mint.clone(), + authority: std::option::Option::Some(target.clone()), + program_id: std::option::Option::Some(target.clone()), + }, + 36_u8, + 0_u8, + 1_usize, + ), + ( + crate::ExSplTokenSingleOperation::UpdateTransferHook { + mint: mint.clone(), + authority: sauthority.clone(), + program_id: std::option::Option::None, + }, + 36_u8, + 1_u8, + 4_usize, + ), + ( + crate::ExSplTokenSingleOperation::InitializeMetadataPointer { + mint: mint.clone(), + authority: std::option::Option::Some(target.clone()), + metadata_address: std::option::Option::Some(target.clone()), + }, + 39_u8, + 0_u8, + 1_usize, + ), + ( + crate::ExSplTokenSingleOperation::UpdateMetadataPointer { + mint: mint.clone(), + authority: sauthority.clone(), + metadata_address: std::option::Option::None, + }, + 39_u8, + 1_u8, + 4_usize, + ), + ( + crate::ExSplTokenSingleOperation::InitializeGroupPointer { + mint: mint.clone(), + authority: std::option::Option::Some(target.clone()), + group_address: std::option::Option::Some(target.clone()), + }, + 40_u8, + 0_u8, + 1_usize, + ), + ( + crate::ExSplTokenSingleOperation::UpdateGroupPointer { + mint: mint.clone(), + authority: sauthority.clone(), + group_address: std::option::Option::None, + }, + 40_u8, + 1_u8, + 4_usize, + ), + ( + crate::ExSplTokenSingleOperation::InitializeGroupMemberPointer { + mint: mint.clone(), + authority: std::option::Option::Some(target.clone()), + member_address: std::option::Option::Some(target), + }, + 41_u8, + 0_u8, + 1_usize, + ), + ( + crate::ExSplTokenSingleOperation::UpdateGroupMemberPointer { + mint, + authority: sauthority, + member_address: std::option::Option::None, + }, + 41_u8, + 1_u8, + 4_usize, + ), + ]; + for (operation, outer_tag, sub_tag, account_count) in cases { + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("hook or pointer plan failed: {error}")); + assert_eq!(plan.instructions[0].data[0], outer_tag); + assert_eq!(plan.instructions[0].data[1], sub_tag); + assert_eq!(plan.instructions[0].accounts.len(), account_count); + assert!(plan.instructions[0].accounts[0].is_writable); + } + } + + #[test] + fn metadata_and_group_interface_builders_preserve_discriminated_wire_and_accounts() { + let first = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let second = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let third = pubkey(kb_program_ids::STAKE_PROGRAM_ID); + let cases = [ + ( + crate::ExSplTokenSingleOperation::InitializeTokenMetadata { + metadata: first.clone(), + update_authority: second.clone(), + mint: first.clone(), + mint_authority: third.clone(), + name: std::string::String::from("Token"), + symbol: std::string::String::from("TKN"), + uri: std::string::String::from("https://example.invalid/token.json"), + }, + 4_usize, + ), + ( + crate::ExSplTokenSingleOperation::UpdateTokenMetadataField { + metadata: first.clone(), + update_authority: second.clone(), + field: crate::ExSplTokenMetadataField::Key(std::string::String::from( + "website", + )), + value: std::string::String::from("https://example.invalid"), + }, + 2_usize, + ), + ( + crate::ExSplTokenSingleOperation::RemoveTokenMetadataKey { + metadata: first.clone(), + update_authority: second.clone(), + key: std::string::String::from("website"), + idempotent: true, + }, + 2_usize, + ), + ( + crate::ExSplTokenSingleOperation::InitializeTokenGroup { + group: first.clone(), + mint: first.clone(), + mint_authority: second.clone(), + update_authority: std::option::Option::Some(third.clone()), + max_size: 42, + }, + 3_usize, + ), + ( + crate::ExSplTokenSingleOperation::UpdateTokenGroupMaxSize { + group: first.clone(), + update_authority: second.clone(), + max_size: 84, + }, + 2_usize, + ), + ( + crate::ExSplTokenSingleOperation::InitializeTokenGroupMember { + member: first.clone(), + member_mint: first.clone(), + member_mint_authority: second.clone(), + group: third.clone(), + group_update_authority: second, + }, + 5_usize, + ), + ]; + for (operation, account_count) in cases { + let intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("metadata or group plan failed: {error}")); + assert!(plan.instructions[0].data.len() >= 8); + assert_eq!(plan.instructions[0].accounts.len(), account_count); + assert!(plan.instructions[0].accounts[0].is_writable); + } + } + + #[test] + fn recent_unwrap_is_constructible_and_batch_is_explicitly_decode_only() { + let unwrap = crate::ExSplTokenSingleOperation::UnwrapLamports { + account: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + destination: pubkey(kb_program_ids::STAKE_PROGRAM_ID), + authority: authority(&[]), + amount_lamports: std::option::Option::Some(crate::ExSplTokenAmount( + std::string::String::from("42"), + )), + }; + let unwrap_intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(unwrap.clone()), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &unwrap_intent, + ) + .unwrap_or_else(|error| panic!("recent unwrap plan failed: {error}")); + assert_eq!(plan.instructions[0].data[0], 45); + assert_eq!(plan.requested_spend_lamports, 42); + + let batch_intent = intent(crate::ExSplToken2022Operation::Batch { + instructions: vec![unwrap, transfer_checked()], + }); + let error = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &batch_intent, + ) + .expect_err("Batch must remain decode-only without an official interface builder"); + assert_eq!(error.code(), "execution_spl_token_2022_batch_builder_unavailable"); + } + + #[test] + fn invalid_amount_multisig_and_optional_simulation_fail_closed() { + let mut operation = transfer_checked(); + if let crate::ExSplTokenSingleOperation::TransferChecked { amount, .. } = &mut operation { + amount.0 = std::string::String::from("-1"); + } + let pintent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let error = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &pintent, + ) + .expect_err("negative amount must fail"); + assert_eq!(error.code(), "execution_spl_token_2022_amount_invalid"); + + let mut intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(transfer_checked()), + }); + intent.policy.simulation = crate::ExApiExecutionSimulationPolicy::Optional; + let error = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .expect_err("optional simulation must fail"); + assert_eq!(error.code(), "execution_spl_token_2022_simulation_required"); + } + + #[test] + fn every_cluster_is_constructible_and_mainnet_remains_governed_by_common_safety() { + for cluster in [ + crate::ExApiExecutionCluster::Localnet, + crate::ExApiExecutionCluster::Devnet, + crate::ExApiExecutionCluster::Testnet, + crate::ExApiExecutionCluster::Mainnet, + ] { + let mut intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(transfer_checked()), + }); + intent.policy.cluster.expected_cluster = cluster; + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &intent, + ) + .unwrap_or_else(|error| panic!("cluster plan failed: {error}")); + assert_eq!(plan.policy.cluster.expected_cluster, cluster); + let evaluation = crate::ExSafetyChecker + .evaluate_prepared_plan(&plan) + .unwrap_or_else(|error| panic!("safety evaluation failed: {error}")); + if cluster == crate::ExApiExecutionCluster::Mainnet { + assert_eq!(evaluation.decision, crate::ExSafetyDecision::Deny); + assert!(evaluation.violations.iter().any(|violation| { + return violation.code == "execution_mainnet_disabled"; + })); + let mut explicitly_enabled = plan.clone(); + explicitly_enabled.policy.cluster.allow_mainnet = true; + explicitly_enabled.policy.cluster.mainnet_confirmation = true; + let enabled_evaluation = crate::ExSafetyChecker + .evaluate_prepared_plan(&explicitly_enabled) + .unwrap_or_else(|error| { + panic!("enabled Mainnet safety evaluation failed: {error}") + }); + assert_eq!(enabled_evaluation.decision, crate::ExSafetyDecision::Allow); + } else { + assert_eq!(evaluation.decision, crate::ExSafetyDecision::Allow); + } + } + } + + #[test] + fn transfer_fee_builders_preserve_exact_wire_accounts_and_bounds() { + let source = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID); + let mint = pubkey(kb_program_ids::CONFIG_PROGRAM_ID); + let destination = pubkey(kb_program_ids::STAKE_PROGRAM_ID); + let signer = pubkey(kb_program_ids::VOTE_PROGRAM_ID); + let operation = crate::ExSplTokenSingleOperation::TransferCheckedWithFee { + source: source.clone(), + mint: mint.clone(), + destination: destination.clone(), + authority: crate::ExSplTokenAuthority { + authority: pubkey(kb_program_ids::FEATURE_PROGRAM_ID), + multisig_signers: vec![signer.clone()], + }, + amount: crate::ExSplTokenAmount(std::string::String::from("42")), + decimals: 9, + fee: crate::ExSplTokenAmount(std::string::String::from("2")), + }; + let pintent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(operation), + }); + let plan = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &pintent, + ) + .unwrap_or_else(|error| panic!("transfer fee plan failed: {error}")); + let instruction = &plan.instructions[0]; + assert_eq!(instruction.data[0], 26); + assert_eq!(instruction.data[1], 1); + assert_eq!(&instruction.data[2..10], &42_u64.to_le_bytes()); + assert_eq!(instruction.data[10], 9); + assert_eq!(&instruction.data[11..19], &2_u64.to_le_bytes()); + assert_eq!(instruction.accounts.len(), 5); + assert_eq!(instruction.accounts[0].pubkey, source); + assert!(instruction.accounts[0].is_writable); + assert_eq!(instruction.accounts[1].pubkey, mint); + assert!(!instruction.accounts[1].is_writable); + assert_eq!(instruction.accounts[2].pubkey, destination); + assert!(instruction.accounts[2].is_writable); + assert!(!instruction.accounts[3].is_signer); + assert_eq!(instruction.accounts[4].pubkey, signer); + assert!(instruction.accounts[4].is_signer); + + let invalid = crate::ExSplTokenSingleOperation::InitializeTransferFeeConfig { + mint: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID), + transfer_fee_config_authority: std::option::Option::None, + withdraw_withheld_authority: std::option::Option::None, + transfer_fee_basis_points: 10_001, + maximum_fee: crate::ExSplTokenAmount(std::string::String::from("0")), + }; + let invalid_intent = intent(crate::ExSplToken2022Operation::Instruction { + value: std::boxed::Box::new(invalid), + }); + let error = crate::ExApiTypedInstructionExecutor::build_prepared_plan( + &crate::ExSplToken2022Executor, + &invalid_intent, + ) + .expect_err("basis points above 100% must fail"); + assert_eq!(error.code(), "execution_spl_token_2022_transfer_fee_basis_points_invalid"); + } +} diff --git a/kb-lib/src/executor/spl/token2022/confidential.rs b/kb-lib/src/executor/spl/token2022/confidential.rs new file mode 100644 index 0000000..5090a9b --- /dev/null +++ b/kb-lib/src/executor/spl/token2022/confidential.rs @@ -0,0 +1,601 @@ +// file: kb-lib/src/executor/spl/token2022/confidential.rs +// version: 8 + +//! Audited Confidential Transfer execution contracts. + +use ts_rs::TS; // rust-rules: derive-import + +/// Maximum number of proof references accepted by one confidential operation. +pub const EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES: usize = 5; +/// Exact byte length of an ElGamal public key accepted from callers. +pub const EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES: usize = 32; +/// Exact byte length of one decryptable authenticated balance ciphertext. +pub const EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES: usize = 36; +/// Exact byte length of one ElGamal ciphertext accepted from callers. +pub const EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES: usize = 64; +/// Token-2022 outer tag shared by all Confidential Transfer instructions. +pub const EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG: u8 = 27; +/// Confidential Transfer subtag published for `TransferWithFee`. +pub const EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG: u8 = 13; +/// Exact payload bytes after the two instruction discriminants for `TransferWithFee`. +pub const EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES: usize = + EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES + + (EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES * 2) + + EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES; +/// Exact total Token-2022 instruction-data bytes for `TransferWithFee`. +pub const EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES: usize = + 2 + EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES; + +/// Caller-generated ElGamal public key encoded as lowercase or uppercase hexadecimal. +#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenElGamalPubkey.ts" +)] +pub struct ExSplTokenElGamalPubkey(pub std::string::String); + +impl ExSplTokenElGamalPubkey { + pub(crate) fn parse( + &self, + ) -> Result { + let bytes = match decode_exact_hex( + &self.0, + EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES, + "ElGamal public key", + ) { + Ok(value) => value, + Err(error) => return Err(error), + }; + let array = match <[u8; EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES]>::try_from(bytes.as_slice()) + { + Ok(value) => value, + Err(_) => return Err("ElGamal public key has an invalid length".to_owned()), + }; + return Ok(bytemuck::pod_read_unaligned(array.as_slice())); + } +} + +/// Caller-generated decryptable balance encoded as hexadecimal bytes. +#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenDecryptableBalance.ts" +)] +pub struct ExSplTokenDecryptableBalance(pub std::string::String); + +impl ExSplTokenDecryptableBalance { + pub(crate) fn parse( + &self, + ) -> Result + { + let bytes = match decode_exact_hex( + &self.0, + EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES, + "decryptable balance", + ) { + Ok(value) => value, + Err(error) => return Err(error), + }; + let array = + match <[u8; EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES]>::try_from(bytes.as_slice()) { + Ok(value) => value, + Err(_) => return Err("decryptable balance has an invalid length".to_owned()), + }; + return Ok(bytemuck::pod_read_unaligned(array.as_slice())); + } +} + +/// Caller-generated ElGamal ciphertext encoded as hexadecimal bytes. +#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenElGamalCiphertext.ts" +)] +pub struct ExSplTokenElGamalCiphertext(pub std::string::String); + +impl ExSplTokenElGamalCiphertext { + pub(crate) fn parse( + &self, + ) -> Result + { + let bytes = match decode_exact_hex( + &self.0, + EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES, + "ElGamal ciphertext", + ) { + Ok(value) => value, + Err(error) => return Err(error), + }; + let array = + match <[u8; EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES]>::try_from(bytes.as_slice()) { + Ok(value) => value, + Err(_) => return Err("ElGamal ciphertext has an invalid length".to_owned()), + }; + return Ok(bytemuck::pod_read_unaligned(array.as_slice())); + } +} + +fn decode_exact_hex( + value: &str, + expected_bytes: usize, + label: &str, +) -> Result, std::string::String> { + if value.len() != expected_bytes.saturating_mul(2) { + return Err(format!( + "{label} must contain exactly {expected_bytes} bytes encoded as hexadecimal" + )); + } + let input = value.as_bytes(); + let mut output = std::vec::Vec::with_capacity(expected_bytes); + let mut index = 0usize; + while index < input.len() { + let high = match decode_hex_nibble(input[index]) { + Some(v) => v, + None => return Err(format!("{label} contains a non-hexadecimal character")), + }; + let low = match decode_hex_nibble(input[index + 1]) { + Some(v) => v, + None => return Err(format!("{label} contains a non-hexadecimal character")), + }; + output.push((high << 4) | low); + index += 2; + } + return Ok(output); +} + +fn decode_hex_nibble(value: u8) -> Option { + return match value { + b'0'..=b'9' => Some(value - b'0'), + b'a'..=b'f' => Some(value - b'a' + 10), + b'A'..=b'F' => Some(value - b'A' + 10), + _ => None, + }; +} + +/// Proof statement required by a Confidential Transfer operation. +#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[serde(rename_all = "snake_case")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialProofKind.ts" +)] +pub enum ExSplTokenConfidentialProofKind { + /// ElGamal public-key validity. + PubkeyValidity, + /// Zero-ciphertext proof used before account closure. + ZeroCiphertext, + /// Ciphertext-commitment equality. + CiphertextCommitmentEquality, + /// Ciphertext-ciphertext equality used by confidential fee withdrawals. + CiphertextCiphertextEquality, + /// Batched grouped-ciphertext validity with three decryption handles. + BatchedGroupedCiphertext3HandlesValidity, + /// Batched grouped-ciphertext validity with two decryption handles. + BatchedGroupedCiphertext2HandlesValidity, + /// Percentage-with-fee sigma proof. + PercentageWithFee, + /// Batched 64-bit range proof. + BatchedRangeProofU64, + /// Batched 128-bit range proof. + BatchedRangeProofU128, + /// Batched 256-bit range proof. + BatchedRangeProofU256, +} + +/// Explicit source for one already-generated zero-knowledge proof statement. +#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[serde(rename_all = "snake_case", tag = "mode")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialProofLocation.ts" +)] +pub enum ExSplTokenConfidentialProofLocation { + /// Relative transaction offset of a separate ZK proof-program instruction. + InstructionOffset { + /// Non-zero signed relative instruction offset. + offset: i8, + }, + /// Account containing a previously verified proof context state. + ContextStateAccount { + /// Proof context-state account. + account: crate::MdPubkey, + }, +} + +impl ExSplTokenConfidentialProofLocation { + /// Validates the mode-specific proof-location contract. + pub fn validate(&self) -> Result<(), std::string::String> { + return match self { + Self::InstructionOffset { offset } if *offset == 0 => Err( + "an inline proof instruction offset must be non-zero; zero is reserved for a context-state account" + .to_owned(), + ), + Self::InstructionOffset { .. } | Self::ContextStateAccount { .. } => Ok(()), + }; + } +} + +/// One proof requirement paired with its explicit location. +#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[serde(rename_all = "camelCase")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialProofReference.ts" +)] +pub struct ExSplTokenConfidentialProofReference { + /// Exact proof statement required by the Token-2022 builder. + pub kind: ExSplTokenConfidentialProofKind, + /// Inline-instruction or context-state source. + pub location: ExSplTokenConfidentialProofLocation, +} + +/// Audited Confidential Transfer operation surface. +#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[serde(rename_all = "snake_case")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialOperation.ts" +)] +pub enum ExSplTokenConfidentialOperation { + /// Initialize confidential-transfer mint configuration. + InitializeMint, + /// Update confidential-transfer mint configuration. + UpdateMint, + /// Configure a token account with an ElGamal key. + ConfigureAccount, + /// Approve a configured account. + ApproveAccount, + /// Empty the available ciphertext before closing an account. + EmptyAccount, + /// Deposit public tokens into pending confidential balance. + Deposit, + /// Withdraw confidential balance into public balance. + Withdraw, + /// Transfer confidentially without a transfer fee. + Transfer, + /// Apply pending balance credits. + ApplyPendingBalance, + /// Enable confidential credits. + EnableConfidentialCredits, + /// Disable confidential credits. + DisableConfidentialCredits, + /// Enable non-confidential credits. + EnableNonConfidentialCredits, + /// Disable non-confidential credits. + DisableNonConfidentialCredits, + /// Transfer confidentially with fee proofs. + TransferWithFee, + /// Configure an account through an ElGamal Registry account. + ConfigureAccountWithRegistry, +} + +impl ExSplTokenConfidentialOperation { + /// Returns the ordered proof statements required by the official builder. + pub fn required_proofs(&self) -> &'static [ExSplTokenConfidentialProofKind] { + return match self { + Self::ConfigureAccount | Self::ConfigureAccountWithRegistry => { + &[ExSplTokenConfidentialProofKind::PubkeyValidity] + }, + Self::EmptyAccount => &[ExSplTokenConfidentialProofKind::ZeroCiphertext], + Self::Withdraw => &[ + ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + ExSplTokenConfidentialProofKind::BatchedRangeProofU64, + ], + Self::Transfer => &[ + ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + ExSplTokenConfidentialProofKind::BatchedRangeProofU128, + ], + Self::TransferWithFee => &[ + ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + ExSplTokenConfidentialProofKind::PercentageWithFee, + ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext2HandlesValidity, + ExSplTokenConfidentialProofKind::BatchedRangeProofU256, + ], + Self::InitializeMint + | Self::UpdateMint + | Self::ApproveAccount + | Self::Deposit + | Self::ApplyPendingBalance + | Self::EnableConfidentialCredits + | Self::DisableConfidentialCredits + | Self::EnableNonConfidentialCredits + | Self::DisableNonConfidentialCredits => &[], + }; + } + + /// Indicates whether the Token-2022 instruction can be constructed without secret material. + pub fn executor_support(&self) -> ExSplTokenConfidentialExecutorSupport { + return match self { + Self::InitializeMint + | Self::UpdateMint + | Self::ApproveAccount + | Self::Deposit + | Self::ApplyPendingBalance + | Self::EnableConfidentialCredits + | Self::DisableConfidentialCredits + | Self::EnableNonConfidentialCredits + | Self::DisableNonConfidentialCredits => { + ExSplTokenConfidentialExecutorSupport::PublicBuilderReady + }, + Self::ConfigureAccount + | Self::EmptyAccount + | Self::Withdraw + | Self::Transfer + | Self::TransferWithFee + | Self::ConfigureAccountWithRegistry => { + ExSplTokenConfidentialExecutorSupport::RequiresCallerGeneratedCryptographicInputs + }, + }; + } +} + +/// Audited Confidential Mint/Burn operation surface. +#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[serde(rename_all = "snake_case")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialMintBurnOperation.ts" +)] +pub enum ExSplTokenConfidentialMintBurnOperation { + /// Initialize the mint extension with supply encryption material. + InitializeMint, + /// Rotate the supply ElGamal public key. + RotateSupplyElGamalPubkey, + /// Replace the caller-maintained decryptable supply. + UpdateDecryptableSupply, + /// Mint tokens directly into a confidential token account. + Mint, + /// Burn tokens from a confidential token account. + Burn, + /// Aggregate the pending burn ciphertext into confidential supply. + ApplyPendingBurn, +} + +impl ExSplTokenConfidentialMintBurnOperation { + /// Returns the published subdiscriminant. + pub fn subtag(&self) -> u8 { + return match self { + Self::InitializeMint => 0, + Self::RotateSupplyElGamalPubkey => 1, + Self::UpdateDecryptableSupply => 2, + Self::Mint => 3, + Self::Burn => 4, + Self::ApplyPendingBurn => 5, + }; + } + + /// Returns the ordered proof statements required by the official builder. + pub fn required_proofs(&self) -> &'static [ExSplTokenConfidentialProofKind] { + return match self { + Self::RotateSupplyElGamalPubkey => { + &[ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality] + }, + Self::Mint | Self::Burn => &[ + ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + ExSplTokenConfidentialProofKind::BatchedRangeProofU128, + ], + Self::InitializeMint | Self::UpdateDecryptableSupply | Self::ApplyPendingBurn => &[], + }; + } + + /// Classifies whether the caller must supply cryptographic material. + pub fn executor_support(&self) -> ExSplTokenConfidentialExecutorSupport { + return match self { + Self::UpdateDecryptableSupply | Self::ApplyPendingBurn => { + ExSplTokenConfidentialExecutorSupport::PublicBuilderReady + }, + Self::InitializeMint | Self::RotateSupplyElGamalPubkey | Self::Mint | Self::Burn => { + ExSplTokenConfidentialExecutorSupport::RequiresCallerGeneratedCryptographicInputs + }, + }; + } +} + +/// Executor-readiness classification established by the Confidential Transfer audit. +#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[serde(rename_all = "snake_case")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialExecutorSupport.ts" +)] +pub enum ExSplTokenConfidentialExecutorSupport { + /// The builder needs only public fields and ordinary authorities. + PublicBuilderReady, + /// The caller must provide ciphertexts, decryptable balances and/or proof data generated outside this executor. + RequiresCallerGeneratedCryptographicInputs, +} + +/// Validates an ordered proof-reference list against the audited operation contract. +pub fn executor_spl_token2022_validate_confidential_proof_references( + operation: ExSplTokenConfidentialOperation, + references: &[ExSplTokenConfidentialProofReference], +) -> Result<(), std::string::String> { + let required = operation.required_proofs(); + if references.len() > EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES { + return Err("too many confidential proof references".to_owned()); + } + if references.len() != required.len() { + return Err( + "confidential proof reference count does not match the operation contract".to_owned() + ); + } + for (index, reference) in references.iter().enumerate() { + if let Err(error) = reference.location.validate() { + return Err(error); + } + if reference.kind != required[index] { + return Err( + "confidential proof references are not in the official builder order".to_owned() + ); + } + } + return Ok(()); +} + +#[cfg(test)] +mod tests { + + #[test] + fn audit_partitions_public_builders_from_caller_generated_cryptographic_inputs() { + assert_eq!( + super::ExSplTokenConfidentialOperation::Deposit.executor_support(), + super::ExSplTokenConfidentialExecutorSupport::PublicBuilderReady + ); + assert_eq!( + super::ExSplTokenConfidentialOperation::Transfer.executor_support(), + super::ExSplTokenConfidentialExecutorSupport::RequiresCallerGeneratedCryptographicInputs + ); + assert_eq!( + super::ExSplTokenConfidentialOperation::ConfigureAccountWithRegistry.executor_support(), + super::ExSplTokenConfidentialExecutorSupport::RequiresCallerGeneratedCryptographicInputs + ); + } + + #[test] + fn opaque_public_inputs_require_exact_hex_lengths() { + let pubkey = super::ExSplTokenElGamalPubkey( + "11".repeat(super::EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES), + ); + assert!(pubkey.parse().is_ok()); + let balance = super::ExSplTokenDecryptableBalance( + "22".repeat(super::EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES), + ); + assert!(balance.parse().is_ok()); + assert!(super::ExSplTokenElGamalPubkey("00".repeat(31)).parse().is_err()); + assert!(super::ExSplTokenDecryptableBalance("zz".repeat(36)).parse().is_err()); + let ciphertext = super::ExSplTokenElGamalCiphertext( + "33".repeat(super::EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES), + ); + assert!(ciphertext.parse().is_ok()); + assert!(super::ExSplTokenElGamalCiphertext("33".repeat(63)).parse().is_err()); + } + + #[test] + fn proof_inventory_preserves_official_transfer_and_fee_order() { + assert_eq!( + super::ExSplTokenConfidentialOperation::Transfer.required_proofs(), + &[ + super::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + super::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + super::ExSplTokenConfidentialProofKind::BatchedRangeProofU128, + ] + ); + assert_eq!( + super::ExSplTokenConfidentialOperation::TransferWithFee.required_proofs(), + &[ + super::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + super::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + super::ExSplTokenConfidentialProofKind::PercentageWithFee, + super::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext2HandlesValidity, + super::ExSplTokenConfidentialProofKind::BatchedRangeProofU256, + ] + ); + } + + #[test] + fn transfer_with_fee_audit_matches_official_wire_and_requires_no_extra_token_payload_ciphertext() + { + assert_eq!(super::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG, 27); + assert_eq!(super::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG, 13); + assert_eq!(super::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES, 169); + assert_eq!( + super::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES, + 171 + ); + assert_eq!( + core::mem::size_of::< + spl_token_2022_interface::extension::confidential_transfer::instruction::TransferWithFeeInstructionData, + >(), + super::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES + ); + assert_eq!( + super::ExSplTokenConfidentialOperation::TransferWithFee.required_proofs().len(), + super::EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES + ); + let decryptable_balance = super::ExSplTokenDecryptableBalance( + "44".repeat(super::EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES), + ); + let auditor_ciphertext_lo = super::ExSplTokenElGamalCiphertext( + "55".repeat(super::EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES), + ); + let auditor_ciphertext_hi = super::ExSplTokenElGamalCiphertext( + "66".repeat(super::EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES), + ); + assert!(decryptable_balance.parse().is_ok()); + assert!(auditor_ciphertext_lo.parse().is_ok()); + assert!(auditor_ciphertext_hi.parse().is_ok()); + } + + #[test] + fn confidential_mint_burn_audit_matches_published_subtags_proofs_and_support() { + assert_eq!(super::ExSplTokenConfidentialMintBurnOperation::InitializeMint.subtag(), 0); + assert_eq!( + super::ExSplTokenConfidentialMintBurnOperation::RotateSupplyElGamalPubkey.subtag(), + 1 + ); + assert_eq!( + super::ExSplTokenConfidentialMintBurnOperation::UpdateDecryptableSupply.subtag(), + 2 + ); + assert_eq!(super::ExSplTokenConfidentialMintBurnOperation::Mint.subtag(), 3); + assert_eq!(super::ExSplTokenConfidentialMintBurnOperation::Burn.subtag(), 4); + assert_eq!(super::ExSplTokenConfidentialMintBurnOperation::ApplyPendingBurn.subtag(), 5); + assert_eq!( + super::ExSplTokenConfidentialMintBurnOperation::RotateSupplyElGamalPubkey + .required_proofs(), + &[super::ExSplTokenConfidentialProofKind::CiphertextCiphertextEquality] + ); + assert_eq!( + super::ExSplTokenConfidentialMintBurnOperation::Mint.required_proofs(), + &[ + super::ExSplTokenConfidentialProofKind::CiphertextCommitmentEquality, + super::ExSplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity, + super::ExSplTokenConfidentialProofKind::BatchedRangeProofU128, + ] + ); + assert_eq!( + super::ExSplTokenConfidentialMintBurnOperation::Burn.required_proofs(), + super::ExSplTokenConfidentialMintBurnOperation::Mint.required_proofs() + ); + assert_eq!( + super::ExSplTokenConfidentialMintBurnOperation::ApplyPendingBurn.executor_support(), + super::ExSplTokenConfidentialExecutorSupport::PublicBuilderReady + ); + assert_eq!( + super::ExSplTokenConfidentialMintBurnOperation::Mint.executor_support(), + super::ExSplTokenConfidentialExecutorSupport::RequiresCallerGeneratedCryptographicInputs + ); + } + + #[test] + fn proof_locations_keep_inline_and_context_state_modes_unambiguous() { + let context_account = crate::MdPubkey("11111111111111111111111111111111".to_owned()); + let references = vec![super::ExSplTokenConfidentialProofReference { + kind: super::ExSplTokenConfidentialProofKind::ZeroCiphertext, + location: super::ExSplTokenConfidentialProofLocation::ContextStateAccount { + account: context_account, + }, + }]; + assert!( + super::executor_spl_token2022_validate_confidential_proof_references( + super::ExSplTokenConfidentialOperation::EmptyAccount, + &references + ) + .is_ok() + ); + let invalid = vec![super::ExSplTokenConfidentialProofReference { + kind: super::ExSplTokenConfidentialProofKind::ZeroCiphertext, + location: super::ExSplTokenConfidentialProofLocation::InstructionOffset { offset: 0 }, + }]; + assert!( + super::executor_spl_token2022_validate_confidential_proof_references( + super::ExSplTokenConfidentialOperation::EmptyAccount, + &invalid + ) + .is_err() + ); + } +} diff --git a/kb-lib/src/executor/spl/token2022/constants.rs b/kb-lib/src/executor/spl/token2022/constants.rs new file mode 100644 index 0000000..9a6c028 --- /dev/null +++ b/kb-lib/src/executor/spl/token2022/constants.rs @@ -0,0 +1,13 @@ +// file: kb-lib/src/executor/spl/token2022/constants.rs +// version: 5 + +//! Local constants for the `kb_executor_spl_token_2022` crate. Program identifiers live in `kb_program_ids`. + +/// Maximum number of ordered multisig signer occurrences. +pub(crate) const EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS: usize = 11; +/// Maximum UI amount string length accepted before transaction assembly. +pub(crate) const EX_SPL_TOKEN2022_MAX_UI_AMOUNT_BYTES: usize = 255; +/// Maximum ordered token accounts accepted by transfer-fee harvest or withdraw builders. +pub(crate) const EX_SPL_TOKEN2022_MAX_TRANSFER_FEE_SOURCE_ACCOUNTS: usize = 255; +/// Canonical tracing target for this crate. +pub(crate) const EX_SPL_TOKEN2022_TRACING_TARGET: &str = "kb-lib.executor.spl.token2022"; diff --git a/kb-lib/src/executor/spl/token2022/executor.rs b/kb-lib/src/executor/spl/token2022/executor.rs new file mode 100644 index 0000000..b758ea0 --- /dev/null +++ b/kb-lib/src/executor/spl/token2022/executor.rs @@ -0,0 +1,333 @@ +// file: kb-lib/src/executor/spl/token2022/executor.rs +// version: 20 + +//! Exact Token-2022 capability dispatch and typed plan construction. + +/// Token-2022 executor implementation. +#[derive(Clone, Debug, Default)] +pub struct ExSplToken2022Executor; + +impl crate::ExSplToken2022Executor { + fn exact_capability( + &self, + program_id: &crate::MdProgramId, + operation_code: &str, + ) -> crate::ExApiExecutionCapability { + if program_id.0 != kb_program_ids::SPL_TOKEN2022_PROGRAM_ID { + return crate::ExApiExecutionCapability::unsupported( + "execution_spl_token_2022_program_not_owned", + format!("program {} is not owned by kb_executor_spl_token_2022", program_id.0), + ); + } + if crate::EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES.contains(&operation_code) { + return crate::ExApiExecutionCapability::supported(operation_code); + } + if operation_code == crate::EX_SPL_TOKEN2022_BATCH_OPERATION { + return crate::ExApiExecutionCapability::unsupported( + "execution_spl_token_2022_batch_builder_unavailable", + "Token-2022 Batch is decode-only because spl-token-2022-interface 3.1.1 publishes no official Batch builder", + ); + } + if matches!( + operation_code, + "spl_token_2022.initialize_mint_with_rent" + | "spl_token_2022.initialize_account_with_rent" + | "spl_token_2022.initialize_multisig_with_rent" + | "spl_token_2022.initialize_account2" + ) { + return crate::ExApiExecutionCapability::unsupported( + "execution_spl_token_2022_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_2022_operation_unsupported", + format!("SPL Token operation {operation_code} is not implemented"), + ); + } +} + +impl crate::ExApiTypedInstructionExecutor for crate::ExSplToken2022Executor { + type Intent = crate::ExSplToken2022ExecutionIntent; + + 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 { + let program_id = + crate::MdProgramId(std::string::String::from(kb_program_ids::SPL_TOKEN2022_PROGRAM_ID)); + return match self.exact_capability(&program_id, intent.operation.operation_code()) { + crate::ExApiExecutionCapability::Supported { operation_code: _ } => { + crate::executor_spl_token2022_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::ExSplToken2022Executor { + fn executor_name(&self) -> &'static str { + return "kb_executor_spl_token_2022"; + } + + fn executor_version(&self) -> &'static str { + return env!("CARGO_PKG_VERSION"); + } + + fn program_ids(&self) -> &'static [&'static str] { + return &[kb_program_ids::SPL_TOKEN2022_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 { + 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::( + &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_2022_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_2022_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_2022"), + 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::ExSplToken2022Executor; + for operation_code in crate::EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES { + let request = request(kb_program_ids::SPL_TOKEN2022_PROGRAM_ID, operation_code); + assert_eq!( + crate::ExApiInstructionExecutor::supports_request(&executor, &request), + crate::ExApiExecutionSupport::Yes + ); + } + for operation_code in [ + "spl_token_2022.initialize_mint_with_rent", + "spl_token_2022.initialize_account_with_rent", + "spl_token_2022.initialize_multisig_with_rent", + "spl_token_2022.initialize_account2", + ] { + let capability = crate::ExApiTypedInstructionExecutor::capability( + &executor, + &crate::MdProgramId(kb_program_ids::SPL_TOKEN2022_PROGRAM_ID.to_string()), + operation_code, + ); + match capability { + crate::ExApiExecutionCapability::Unsupported { reason_code, reason: _ } => { + assert_eq!( + reason_code, + "execution_spl_token_2022_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::ExSplToken2022Executor; + let foreign = request( + kb_program_ids::SPL_TOKEN_PROGRAM_ID, + crate::EX_SPL_TOKEN2022_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::(include_str!( + "../../../../../docs/SPL_TOKEN2022_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 extension_types = matrix["extensionTypes"] + .as_array() + .unwrap_or_else(|| panic!("matrix extensionTypes must be an array")); + let matrix_names = instructions + .iter() + .chain(extension_types.iter()) + .filter_map(|instruction| return instruction["name"].as_str()) + .collect::>(); + assert_eq!(instructions.len(), 48); + for operation_code in crate::EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES { + let name = operation_code + .strip_prefix("spl_token_2022.") + .unwrap_or_else(|| panic!("invalid operation code {operation_code}")); + let matrix_name = match name { + "initialize_interest_bearing_mint" | "update_interest_bearing_rate" => { + "interest_bearing_mint_extension" + }, + "initialize_transfer_fee_config" + | "set_transfer_fee" + | "transfer_checked_with_fee" + | "withdraw_withheld_tokens_from_mint" + | "withdraw_withheld_tokens_from_accounts" + | "harvest_withheld_tokens_to_mint" => "transfer_fee_extension", + "initialize_default_account_state" | "update_default_account_state" => { + "default_account_state_extension" + }, + "enable_required_transfer_memos" | "disable_required_transfer_memos" => { + "memo_transfer_extension" + }, + "enable_cpi_guard" | "disable_cpi_guard" => "cpi_guard_extension", + "initialize_transfer_hook" | "update_transfer_hook" => "transfer_hook_extension", + "initialize_metadata_pointer" | "update_metadata_pointer" => { + "metadata_pointer_extension" + }, + "initialize_group_pointer" | "update_group_pointer" => "group_pointer_extension", + "initialize_group_member_pointer" | "update_group_member_pointer" => { + "group_member_pointer_extension" + }, + "initialize_token_metadata" + | "update_token_metadata_field" + | "remove_token_metadata_key" => "token_metadata", + "initialize_token_group" | "update_token_group_max_size" => "token_group", + "initialize_token_group_member" => "token_group_member", + "initialize_scaled_ui_amount" | "update_scaled_ui_amount_multiplier" => { + "scaled_ui_amount_extension" + }, + "initialize_pausable_config" | "pause" | "resume" => "pausable_extension", + "initialize_permissioned_burn" + | "permissioned_burn" + | "permissioned_burn_checked" + | "permissioned_confidential_burn" => "permissioned_burn_extension", + "initialize_confidential_transfer_mint" + | "update_confidential_transfer_mint" + | "apply_pending_confidential_balance" + | "approve_confidential_transfer_account" + | "deposit_confidential_tokens" + | "enable_confidential_credits" + | "disable_confidential_credits" + | "enable_non_confidential_credits" + | "disable_non_confidential_credits" + | "configure_confidential_transfer_account" + | "configure_confidential_transfer_account_with_registry" + | "empty_confidential_transfer_account" + | "withdraw_confidential_tokens" + | "transfer_confidential_tokens" + | "transfer_confidential_tokens_with_fee" => "confidential_transfer_extension", + "initialize_confidential_transfer_fee_config" + | "enable_confidential_transfer_fee_harvest" + | "disable_confidential_transfer_fee_harvest" + | "harvest_confidential_withheld_tokens_to_mint" + | "withdraw_confidential_withheld_tokens_from_mint" + | "withdraw_confidential_withheld_tokens_from_accounts" => { + "confidential_transfer_fee_extension" + }, + "initialize_confidential_mint_burn_mint" + | "rotate_confidential_supply_elgamal_pubkey" + | "update_confidential_decryptable_supply" + | "apply_pending_confidential_burn" + | "confidential_mint" + | "confidential_burn" => "confidential_mint_burn_extension", + _ => name, + }; + assert!( + matrix_names.contains(matrix_name), + "matrix is missing supported operation {name}" + ); + } + assert!(matrix_names.contains("batch")); + let batch = crate::ExApiTypedInstructionExecutor::capability( + &crate::ExSplToken2022Executor, + &crate::MdProgramId(kb_program_ids::SPL_TOKEN2022_PROGRAM_ID.to_string()), + crate::EX_SPL_TOKEN2022_BATCH_OPERATION, + ); + match batch { + crate::ExApiExecutionCapability::Unsupported { reason_code, reason: _ } => { + assert_eq!(reason_code, "execution_spl_token_2022_batch_builder_unavailable"); + }, + crate::ExApiExecutionCapability::Supported { operation_code: _ } => { + panic!("Batch must remain decode-only"); + }, + } + } +} diff --git a/kb-lib/src/executor/spl/token2022/intent.rs b/kb-lib/src/executor/spl/token2022/intent.rs new file mode 100644 index 0000000..1289409 --- /dev/null +++ b/kb-lib/src/executor/spl/token2022/intent.rs @@ -0,0 +1,1629 @@ +// file: kb-lib/src/executor/spl/token2022/intent.rs +// version: 24 + +//! Typed Token-2022 execution intents. + +use ts_rs::TS; // rust-rules: derive-import + +/// Stable operation code for mint initialization through `InitializeMint2`. +pub const EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION: &str = "spl_token_2022.initialize_mint"; +/// Stable operation code for token-account initialization through `InitializeAccount3`. +pub const EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION: &str = "spl_token_2022.initialize_account"; +/// Stable operation code for multisig initialization through `InitializeMultisig2`. +pub const EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION: &str = + "spl_token_2022.initialize_multisig"; +/// Stable operation code for an unchecked token transfer. +pub const EX_SPL_TOKEN2022_TRANSFER_OPERATION: &str = "spl_token_2022.transfer"; +/// Stable operation code for an approval. +pub const EX_SPL_TOKEN2022_APPROVE_OPERATION: &str = "spl_token_2022.approve"; +/// Stable operation code for a delegate revocation. +pub const EX_SPL_TOKEN2022_REVOKE_OPERATION: &str = "spl_token_2022.revoke"; +/// Stable operation code for an authority change. +pub const EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION: &str = "spl_token_2022.set_authority"; +/// Stable operation code for minting tokens. +pub const EX_SPL_TOKEN2022_MINT_TO_OPERATION: &str = "spl_token_2022.mint_to"; +/// Stable operation code for burning tokens. +pub const EX_SPL_TOKEN2022_BURN_OPERATION: &str = "spl_token_2022.burn"; +/// Stable operation code for closing a token account. +pub const EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION: &str = "spl_token_2022.close_account"; +/// Stable operation code for freezing a token account. +pub const EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION: &str = "spl_token_2022.freeze_account"; +/// Stable operation code for thawing a token account. +pub const EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION: &str = "spl_token_2022.thaw_account"; +/// Stable operation code for a checked token transfer. +pub const EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION: &str = "spl_token_2022.transfer_checked"; +/// Stable operation code for a checked approval. +pub const EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION: &str = "spl_token_2022.approve_checked"; +/// Stable operation code for checked minting. +pub const EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION: &str = "spl_token_2022.mint_to_checked"; +/// Stable operation code for checked burning. +pub const EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION: &str = "spl_token_2022.burn_checked"; +/// Stable operation code for synchronizing wrapped SOL. +pub const EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION: &str = "spl_token_2022.sync_native"; +/// Stable operation code for querying account data size. +pub const EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION: &str = + "spl_token_2022.get_account_data_size"; +/// Stable operation code for the classic compatibility no-op. +pub const EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION: &str = + "spl_token_2022.initialize_immutable_owner"; +/// Stable operation code for raw-to-UI amount conversion. +pub const EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION: &str = + "spl_token_2022.amount_to_ui_amount"; +/// Stable operation code for UI-to-raw amount conversion. +pub const EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION: &str = + "spl_token_2022.ui_amount_to_amount"; +/// Stable operation code for rescuing excess lamports. +pub const EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION: &str = + "spl_token_2022.withdraw_excess_lamports"; +/// Stable operation code for the recent wrapped-SOL partial unwrap. +pub const EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION: &str = "spl_token_2022.unwrap_lamports"; +/// Stable operation code for Token-2022 account reallocation. +pub const EX_SPL_TOKEN2022_REALLOCATE_OPERATION: &str = "spl_token_2022.reallocate"; +/// Stable operation code for initializing a non-transferable mint. +pub const EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION: &str = + "spl_token_2022.initialize_non_transferable_mint"; +/// Stable operation code for initializing a permanent delegate. +pub const EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION: &str = + "spl_token_2022.initialize_permanent_delegate"; +/// Stable operation code for initializing an interest-bearing mint. +pub const EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION: &str = + "spl_token_2022.initialize_interest_bearing_mint"; +/// Stable operation code for updating an interest-bearing mint rate. +pub const EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION: &str = + "spl_token_2022.update_interest_bearing_rate"; +/// Stable operation code for transfer-fee configuration initialization. +pub const EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION: &str = + "spl_token_2022.initialize_transfer_fee_config"; +/// Stable operation code for updating transfer-fee parameters. +pub const EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION: &str = "spl_token_2022.set_transfer_fee"; +/// Stable operation code for a checked transfer with an expected fee. +pub const EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION: &str = + "spl_token_2022.transfer_checked_with_fee"; +/// Stable operation code for withdrawing withheld fees from a mint. +pub const EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION: &str = + "spl_token_2022.withdraw_withheld_tokens_from_mint"; +/// Stable operation code for withdrawing withheld fees from token accounts. +pub const EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION: &str = + "spl_token_2022.withdraw_withheld_tokens_from_accounts"; +/// Stable operation code for harvesting withheld fees into a mint. +pub const EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION: &str = + "spl_token_2022.harvest_withheld_tokens_to_mint"; +/// Stable operation code for initializing a default account state. +pub const EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION: &str = + "spl_token_2022.initialize_default_account_state"; +/// Stable operation code for updating a default account state. +pub const EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION: &str = + "spl_token_2022.update_default_account_state"; +/// Stable operation code for requiring memos on incoming transfers. +pub const EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION: &str = + "spl_token_2022.enable_required_transfer_memos"; +/// Stable operation code for disabling required incoming-transfer memos. +pub const EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION: &str = + "spl_token_2022.disable_required_transfer_memos"; +/// Stable operation code for enabling CPI Guard on a token account. +pub const EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION: &str = "spl_token_2022.enable_cpi_guard"; +/// Stable operation code for disabling CPI Guard on a token account. +pub const EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION: &str = "spl_token_2022.disable_cpi_guard"; +/// Stable operation code for initializing a transfer-hook pointer. +pub const EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION: &str = + "spl_token_2022.initialize_transfer_hook"; +/// Stable operation code for updating or clearing a transfer-hook program id. +pub const EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION: &str = + "spl_token_2022.update_transfer_hook"; +/// Stable operation code for initializing a metadata pointer. +pub const EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION: &str = + "spl_token_2022.initialize_metadata_pointer"; +/// Stable operation code for updating or clearing a metadata pointer. +pub const EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION: &str = + "spl_token_2022.update_metadata_pointer"; +/// Stable operation code for initializing a group pointer. +pub const EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION: &str = + "spl_token_2022.initialize_group_pointer"; +/// Stable operation code for updating or clearing a group pointer. +pub const EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION: &str = + "spl_token_2022.update_group_pointer"; +/// Stable operation code for initializing a group-member pointer. +pub const EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION: &str = + "spl_token_2022.initialize_group_member_pointer"; +/// Stable operation code for updating or clearing a group-member pointer. +pub const EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION: &str = + "spl_token_2022.update_group_member_pointer"; +/// Stable operation code for initializing Token-2022 embedded metadata. +pub const EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION: &str = + "spl_token_2022.initialize_token_metadata"; +/// Stable operation code for updating an embedded metadata field. +pub const EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION: &str = + "spl_token_2022.update_token_metadata_field"; +/// Stable operation code for removing an embedded metadata key. +pub const EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION: &str = + "spl_token_2022.remove_token_metadata_key"; +/// Stable operation code for initializing an embedded token group. +pub const EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION: &str = + "spl_token_2022.initialize_token_group"; +/// Stable operation code for updating an embedded token-group maximum size. +pub const EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION: &str = + "spl_token_2022.update_token_group_max_size"; +/// Stable operation code for initializing an embedded token-group member. +pub const EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION: &str = + "spl_token_2022.initialize_token_group_member"; +/// Stable operation code for initializing scaled UI amounts. +pub const EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION: &str = + "spl_token_2022.initialize_scaled_ui_amount"; +/// Stable operation code for scheduling a scaled UI multiplier update. +pub const EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION: &str = + "spl_token_2022.update_scaled_ui_amount_multiplier"; +/// Stable operation code for initializing pausable mint state. +pub const EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION: &str = + "spl_token_2022.initialize_pausable_config"; +/// Stable operation code for pausing mint activity. +pub const EX_SPL_TOKEN2022_PAUSE_OPERATION: &str = "spl_token_2022.pause"; +/// Stable operation code for resuming mint activity. +pub const EX_SPL_TOKEN2022_RESUME_OPERATION: &str = "spl_token_2022.resume"; +/// Stable operation code for initializing permissioned burn. +pub const EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION: &str = + "spl_token_2022.initialize_permissioned_burn"; +/// Stable operation code for a permissioned burn. +pub const EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION: &str = "spl_token_2022.permissioned_burn"; +/// Stable operation code for a checked permissioned burn. +pub const EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION: &str = + "spl_token_2022.permissioned_burn_checked"; +/// Stable operation code for initializing Confidential Transfer mint configuration. +pub const EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION: &str = + "spl_token_2022.initialize_confidential_transfer_mint"; +/// Stable operation code for updating Confidential Transfer mint configuration. +pub const EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION: &str = + "spl_token_2022.update_confidential_transfer_mint"; +/// Stable operation code for applying pending confidential balance credits. +pub const EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION: &str = + "spl_token_2022.apply_pending_confidential_balance"; +/// Stable operation code for approving a configured confidential account. +pub const EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION: &str = + "spl_token_2022.approve_confidential_transfer_account"; +/// Stable operation code for depositing public tokens into a confidential pending balance. +pub const EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION: &str = + "spl_token_2022.deposit_confidential_tokens"; +/// Stable operation code for enabling incoming confidential credits. +pub const EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION: &str = + "spl_token_2022.enable_confidential_credits"; +/// Stable operation code for disabling incoming confidential credits. +pub const EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION: &str = + "spl_token_2022.disable_confidential_credits"; +/// Stable operation code for enabling incoming non-confidential credits. +pub const EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION: &str = + "spl_token_2022.enable_non_confidential_credits"; +/// Stable operation code for disabling incoming non-confidential credits. +pub const EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION: &str = + "spl_token_2022.disable_non_confidential_credits"; +/// Stable operation code for configuring one confidential token account. +pub const EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION: &str = + "spl_token_2022.configure_confidential_transfer_account"; +/// Stable operation code for configuring one confidential token account through the registry. +pub const EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION: &str = + "spl_token_2022.configure_confidential_transfer_account_with_registry"; +/// Stable operation code for emptying a confidential available balance before close. +pub const EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION: &str = + "spl_token_2022.empty_confidential_transfer_account"; +/// Stable operation code for withdrawing confidential balance into public balance. +pub const EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION: &str = + "spl_token_2022.withdraw_confidential_tokens"; +/// Stable operation code for transferring confidential tokens. +pub const EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION: &str = + "spl_token_2022.transfer_confidential_tokens"; +/// Stable operation code for confidential transfer with fee. +pub const EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION: &str = + "spl_token_2022.transfer_confidential_tokens_with_fee"; +/// Stable operation code for initializing confidential transfer fee configuration. +pub const EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION: &str = + "spl_token_2022.initialize_confidential_transfer_fee_config"; +/// Stable operation code for enabling confidential fee harvest to the mint. +pub const EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION: &str = + "spl_token_2022.enable_confidential_transfer_fee_harvest"; +/// Stable operation code for disabling confidential fee harvest to the mint. +pub const EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION: &str = + "spl_token_2022.disable_confidential_transfer_fee_harvest"; +/// Stable operation code for harvesting confidential withheld fees to the mint. +pub const EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION: &str = + "spl_token_2022.harvest_confidential_withheld_tokens_to_mint"; +/// Stable operation code for withdrawing confidential withheld fees from the mint. +pub const EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION: &str = + "spl_token_2022.withdraw_confidential_withheld_tokens_from_mint"; +/// Stable operation code for withdrawing confidential withheld fees from token accounts. +pub const EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION: &str = + "spl_token_2022.withdraw_confidential_withheld_tokens_from_accounts"; +/// Stable operation code for initializing confidential mint and burn. +pub const EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION: &str = + "spl_token_2022.initialize_confidential_mint_burn_mint"; +/// Stable operation code for rotating the confidential supply ElGamal public key. +pub const EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION: &str = + "spl_token_2022.rotate_confidential_supply_elgamal_pubkey"; +/// Stable operation code for updating the decryptable confidential supply. +pub const EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION: &str = + "spl_token_2022.update_confidential_decryptable_supply"; +/// Stable operation code for applying pending confidential burns. +pub const EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION: &str = + "spl_token_2022.apply_pending_confidential_burn"; +/// Stable operation code for confidential minting. +pub const EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION: &str = "spl_token_2022.confidential_mint"; +/// Stable operation code for confidential burning. +pub const EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION: &str = "spl_token_2022.confidential_burn"; +/// Stable operation code for permissioned confidential burning. +pub const EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION: &str = + "spl_token_2022.permissioned_confidential_burn"; + +/// Stable operation code for a recent bounded batch. +pub const EX_SPL_TOKEN2022_BATCH_OPERATION: &str = "spl_token_2022.batch"; + +/// Operation codes constructible by this executor. +pub const EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES: &[&str] = &[ + EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION, + EX_SPL_TOKEN2022_TRANSFER_OPERATION, + EX_SPL_TOKEN2022_APPROVE_OPERATION, + EX_SPL_TOKEN2022_REVOKE_OPERATION, + EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION, + EX_SPL_TOKEN2022_MINT_TO_OPERATION, + EX_SPL_TOKEN2022_BURN_OPERATION, + EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION, + EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION, + EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION, + EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION, + EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION, + EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION, + EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION, + EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION, + EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION, + EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION, + EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION, + EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION, + EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION, + EX_SPL_TOKEN2022_REALLOCATE_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION, + EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION, + EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION, + EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION, + EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION, + EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION, + EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION, + EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION, + EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION, + EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION, + EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION, + EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION, + EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION, + EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION, + EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION, + EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION, + EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION, + EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION, + EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION, + EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION, + EX_SPL_TOKEN2022_PAUSE_OPERATION, + EX_SPL_TOKEN2022_RESUME_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION, + EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION, + EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION, + EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION, + EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION, + EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION, + EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION, + EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION, + EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION, + EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION, + EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION, + EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION, + EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION, + EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION, + EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION, + EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION, + EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION, + EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION, + EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION, + EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION, + EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION, + EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION, + EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION, + EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION, + EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION, + EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION, + EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION, + EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION, + EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_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_executor_spl_token_2022/intent/ExSplTokenAmount.ts" +)] +pub struct ExSplTokenAmount( + /// Canonical unsigned decimal representation. + pub std::string::String, +); + +/// Positive normal finite scaled-UI multiplier represented as a decimal JSON string. +#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenMultiplier.ts" +)] +pub struct ExSplTokenMultiplier( + /// Decimal representation parsed to the official `f64` wire contract. + 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_executor_spl_token_2022/intent/ExSplTokenAuthority.ts" +)] +pub struct ExSplTokenAuthority { + /// 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, +} + +/// 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_executor_spl_token_2022/intent/ExSplTokenAuthorityType.ts" +)] +pub enum ExSplTokenAuthorityType { + /// Mint authority. + MintTokens, + /// Freeze authority. + FreezeAccount, + /// Token-account owner. + AccountOwner, + /// Token-account close authority. + CloseAccount, +} + +/// Default state assigned to newly initialized Token-2022 accounts. +#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[serde(rename_all = "snake_case")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenDefaultAccountState.ts" +)] +pub enum ExSplTokenDefaultAccountState { + /// Newly initialized accounts remain usable. + Initialized, + /// Newly initialized accounts start frozen. + Frozen, +} + +/// Token-metadata field selected for an update. +#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[serde(rename_all = "snake_case", tag = "kind", content = "key")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenMetadataField.ts" +)] +pub enum ExSplTokenMetadataField { + /// Update the required name field. + Name, + /// Update the required symbol field. + Symbol, + /// Update the required URI field. + Uri, + /// Update or create an additional key. + Key(std::string::String), +} + +/// 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_executor_spl_token_2022/intent/ExSplTokenSingleOperation.ts" +)] +pub enum ExSplTokenSingleOperation { + /// 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, + /// 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, + /// 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::ExSplTokenAuthority, + /// Exact raw token amount. + amount: crate::ExSplTokenAmount, + }, + /// 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::ExSplTokenAuthority, + /// Exact raw allowance. + amount: crate::ExSplTokenAmount, + }, + /// Revoke the current delegate. + Revoke { + /// Source token account. + source: crate::MdPubkey, + /// Owner or multisig authority. + authority: crate::ExSplTokenAuthority, + }, + /// Change or revoke an authority. + SetAuthority { + /// Mint or token account whose authority changes. + owned: crate::MdPubkey, + /// Authority domain. + authority_type: crate::ExSplTokenAuthorityType, + /// New authority, or `None` to revoke it. + new_authority: std::option::Option, + /// Current simple or multisig authority. + current_authority: crate::ExSplTokenAuthority, + }, + /// Mint a raw token amount. + MintTo { + /// Mint account. + mint: crate::MdPubkey, + /// Destination token account. + destination: crate::MdPubkey, + /// Mint authority. + authority: crate::ExSplTokenAuthority, + /// Exact raw amount. + amount: crate::ExSplTokenAmount, + }, + /// Burn a raw token amount. + Burn { + /// Source token account. + source: crate::MdPubkey, + /// Mint account. + mint: crate::MdPubkey, + /// Owner, delegate or multisig authority. + authority: crate::ExSplTokenAuthority, + /// Exact raw amount. + amount: crate::ExSplTokenAmount, + }, + /// Close a token account. + CloseAccount { + /// Token account to close. + account: crate::MdPubkey, + /// Lamport destination. + destination: crate::MdPubkey, + /// Owner or close authority. + authority: crate::ExSplTokenAuthority, + }, + /// Freeze a token account. + FreezeAccount { + /// Token account to freeze. + account: crate::MdPubkey, + /// Mint account. + mint: crate::MdPubkey, + /// Freeze authority. + authority: crate::ExSplTokenAuthority, + }, + /// Thaw a token account. + ThawAccount { + /// Token account to thaw. + account: crate::MdPubkey, + /// Mint account. + mint: crate::MdPubkey, + /// Freeze authority. + authority: crate::ExSplTokenAuthority, + }, + /// 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::ExSplTokenAuthority, + /// Exact raw amount. + amount: crate::ExSplTokenAmount, + /// 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::ExSplTokenAuthority, + /// Exact raw allowance. + amount: crate::ExSplTokenAmount, + /// 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::ExSplTokenAuthority, + /// Exact raw amount. + amount: crate::ExSplTokenAmount, + /// 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::ExSplTokenAuthority, + /// Exact raw amount. + amount: crate::ExSplTokenAmount, + /// 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::ExSplTokenAmount, + }, + /// 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::ExSplTokenAuthority, + }, + /// Reallocate a token account to add extension storage. + Reallocate { + /// Token account to grow. + account: crate::MdPubkey, + /// Payer funding rent growth. + payer: crate::MdPubkey, + /// Owner or multisig authority. + authority: crate::ExSplTokenAuthority, + /// Ordered published extension type codes. + extension_types: std::vec::Vec, + }, + /// Initialize the non-transferable mint extension before mint initialization. + InitializeNonTransferableMint { + /// Mint receiving the non-transferable extension. + mint: crate::MdPubkey, + }, + /// Initialize a permanent delegate before mint initialization. + InitializePermanentDelegate { + /// Mint receiving the permanent delegate extension. + mint: crate::MdPubkey, + /// Permanent delegate public key. + delegate: crate::MdPubkey, + }, + /// Initialize interest-bearing configuration before mint initialization. + InitializeInterestBearingMint { + /// Mint receiving the interest-bearing extension. + mint: crate::MdPubkey, + /// Optional authority allowed to update the rate. + rate_authority: std::option::Option, + /// Initial signed interest rate in basis points. + rate_basis_points: i16, + }, + /// Update the interest-bearing rate through a simple or multisig authority. + UpdateInterestBearingRate { + /// Interest-bearing mint to update. + mint: crate::MdPubkey, + /// Current rate authority or multisig authority. + authority: crate::ExSplTokenAuthority, + /// New signed interest rate in basis points. + rate_basis_points: i16, + }, + /// Initialize transfer-fee configuration before mint initialization. + InitializeTransferFeeConfig { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Optional authority allowed to update fee parameters. + transfer_fee_config_authority: std::option::Option, + /// Optional authority allowed to withdraw withheld fees. + withdraw_withheld_authority: std::option::Option, + /// Fee in basis points, bounded by the official interface. + transfer_fee_basis_points: u16, + /// Maximum raw fee amount. + maximum_fee: crate::ExSplTokenAmount, + }, + /// Update transfer-fee parameters. + SetTransferFee { + /// Mint containing `TransferFeeConfig`. + mint: crate::MdPubkey, + /// Current transfer-fee configuration authority. + authority: crate::ExSplTokenAuthority, + /// New fee in basis points. + transfer_fee_basis_points: u16, + /// New maximum raw fee amount. + maximum_fee: crate::ExSplTokenAmount, + }, + /// Transfer a checked amount while asserting the exact expected fee. + TransferCheckedWithFee { + /// Source token account. + source: crate::MdPubkey, + /// Mint account. + mint: crate::MdPubkey, + /// Destination token account. + destination: crate::MdPubkey, + /// Owner, delegate or multisig authority. + authority: crate::ExSplTokenAuthority, + /// Exact raw amount. + amount: crate::ExSplTokenAmount, + /// Mint decimals asserted by the wire. + decimals: u8, + /// Exact expected raw fee. + fee: crate::ExSplTokenAmount, + }, + /// Withdraw all fees withheld by a mint. + WithdrawWithheldTokensFromMint { + /// Mint containing `TransferFeeConfig`. + mint: crate::MdPubkey, + /// Destination token account. + destination: crate::MdPubkey, + /// Withdraw-withheld authority. + authority: crate::ExSplTokenAuthority, + }, + /// Withdraw all fees withheld by an ordered set of token accounts. + WithdrawWithheldTokensFromAccounts { + /// Mint shared by all source accounts. + mint: crate::MdPubkey, + /// Destination token account. + destination: crate::MdPubkey, + /// Withdraw-withheld authority. + authority: crate::ExSplTokenAuthority, + /// Ordered source token accounts. + sources: std::vec::Vec, + }, + /// Permissionlessly harvest withheld fees from token accounts into a mint. + HarvestWithheldTokensToMint { + /// Destination mint. + mint: crate::MdPubkey, + /// Ordered source token accounts. + sources: std::vec::Vec, + }, + /// Initialize the default state for accounts created from a mint. + InitializeDefaultAccountState { + /// Mint receiving the extension before mint initialization. + mint: crate::MdPubkey, + /// Default state for subsequently initialized token accounts. + state: crate::ExSplTokenDefaultAccountState, + }, + /// Update the default state through the mint freeze authority. + UpdateDefaultAccountState { + /// Mint containing the extension. + mint: crate::MdPubkey, + /// Current freeze authority or multisig authority. + authority: crate::ExSplTokenAuthority, + /// New default account state. + state: crate::ExSplTokenDefaultAccountState, + }, + /// Require incoming transfers to be preceded by a memo. + EnableRequiredTransferMemos { + /// Token account to update. + account: crate::MdPubkey, + /// Token-account owner or multisig authority. + authority: crate::ExSplTokenAuthority, + }, + /// Stop requiring incoming-transfer memos. + DisableRequiredTransferMemos { + /// Token account to update. + account: crate::MdPubkey, + /// Token-account owner or multisig authority. + authority: crate::ExSplTokenAuthority, + }, + /// Enable CPI Guard for a token account. + EnableCpiGuard { + /// Token account to update. + account: crate::MdPubkey, + /// Token-account owner or multisig authority. + authority: crate::ExSplTokenAuthority, + }, + /// Disable CPI Guard for a token account. + DisableCpiGuard { + /// Token account to update. + account: crate::MdPubkey, + /// Token-account owner or multisig authority. + authority: crate::ExSplTokenAuthority, + }, + /// Initialize a transfer-hook extension before mint initialization. + InitializeTransferHook { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Optional authority allowed to update the hook program id. + authority: std::option::Option, + /// Optional program invoked during transfers. + program_id: std::option::Option, + }, + /// Update or clear the transfer-hook program id. + UpdateTransferHook { + /// Mint containing the extension. + mint: crate::MdPubkey, + /// Current simple or multisig authority. + authority: crate::ExSplTokenAuthority, + /// New hook program id, or `None` to clear it. + program_id: std::option::Option, + }, + /// Initialize a metadata pointer before mint initialization. + InitializeMetadataPointer { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Optional authority allowed to update the pointer. + authority: std::option::Option, + /// Optional account holding metadata. + metadata_address: std::option::Option, + }, + /// Update or clear a metadata pointer. + UpdateMetadataPointer { + /// Mint containing the extension. + mint: crate::MdPubkey, + /// Current simple or multisig authority. + authority: crate::ExSplTokenAuthority, + /// New metadata account, or `None` to clear it. + metadata_address: std::option::Option, + }, + /// Initialize a group pointer before mint initialization. + InitializeGroupPointer { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Optional authority allowed to update the pointer. + authority: std::option::Option, + /// Optional account holding the group. + group_address: std::option::Option, + }, + /// Update or clear a group pointer. + UpdateGroupPointer { + /// Mint containing the extension. + mint: crate::MdPubkey, + /// Current simple or multisig authority. + authority: crate::ExSplTokenAuthority, + /// New group account, or `None` to clear it. + group_address: std::option::Option, + }, + /// Initialize a group-member pointer before mint initialization. + InitializeGroupMemberPointer { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Optional authority allowed to update the pointer. + authority: std::option::Option, + /// Optional account holding the group member. + member_address: std::option::Option, + }, + /// Update or clear a group-member pointer. + UpdateGroupMemberPointer { + /// Mint containing the extension. + mint: crate::MdPubkey, + /// Current simple or multisig authority. + authority: crate::ExSplTokenAuthority, + /// New group-member account, or `None` to clear it. + member_address: std::option::Option, + }, + /// Initialize Token-2022 metadata in the mint account. + InitializeTokenMetadata { + /// Metadata account, normally the mint itself. + metadata: crate::MdPubkey, + /// Update authority stored in metadata. + update_authority: crate::MdPubkey, + /// Associated mint. + mint: crate::MdPubkey, + /// Current mint authority signer. + mint_authority: crate::MdPubkey, + /// Bounded token name. + name: std::string::String, + /// Bounded token symbol. + symbol: std::string::String, + /// Bounded metadata URI. + uri: std::string::String, + }, + /// Update a required or additional metadata field. + UpdateTokenMetadataField { + /// Metadata account. + metadata: crate::MdPubkey, + /// Current update authority signer. + update_authority: crate::MdPubkey, + /// Field to update. + field: crate::ExSplTokenMetadataField, + /// New bounded value. + value: std::string::String, + }, + /// Remove an additional metadata key. + RemoveTokenMetadataKey { + /// Metadata account. + metadata: crate::MdPubkey, + /// Current update authority signer. + update_authority: crate::MdPubkey, + /// Additional key to remove. + key: std::string::String, + /// Whether a missing key is accepted. + idempotent: bool, + }, + /// Initialize a Token Group entry. + InitializeTokenGroup { + /// Group state account, normally the group mint. + group: crate::MdPubkey, + /// Group mint. + mint: crate::MdPubkey, + /// Current mint authority signer. + mint_authority: crate::MdPubkey, + /// Optional future group update authority. + update_authority: std::option::Option, + /// Maximum number of members. + max_size: u64, + }, + /// Update a Token Group maximum size. + UpdateTokenGroupMaxSize { + /// Group state account. + group: crate::MdPubkey, + /// Current group update authority signer. + update_authority: crate::MdPubkey, + /// New maximum number of members. + max_size: u64, + }, + /// Initialize a Token Group Member entry. + InitializeTokenGroupMember { + /// Member state account, normally the member mint. + member: crate::MdPubkey, + /// Member mint. + member_mint: crate::MdPubkey, + /// Member mint authority signer. + member_mint_authority: crate::MdPubkey, + /// Group state account. + group: crate::MdPubkey, + /// Group update authority signer. + group_update_authority: crate::MdPubkey, + }, + /// Initialize scaled UI amount configuration before mint initialization. + InitializeScaledUiAmount { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Optional future multiplier authority. + authority: std::option::Option, + /// Positive normal finite initial multiplier. + multiplier: crate::ExSplTokenMultiplier, + }, + /// Schedule or immediately apply a scaled UI multiplier update. + UpdateScaledUiAmountMultiplier { + /// Mint containing the extension. + mint: crate::MdPubkey, + /// Current simple or multisig multiplier authority. + authority: crate::ExSplTokenAuthority, + /// Positive normal finite new multiplier. + multiplier: crate::ExSplTokenMultiplier, + /// UNIX timestamp at which the multiplier becomes effective. + effective_timestamp: i64, + }, + /// Initialize pausable configuration before mint initialization. + InitializePausableConfig { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Authority permitted to pause and resume the mint. + authority: crate::MdPubkey, + }, + /// Pause minting, burning and transferring. + Pause { + /// Mint containing pausable configuration. + mint: crate::MdPubkey, + /// Current simple or multisig pause authority. + authority: crate::ExSplTokenAuthority, + }, + /// Resume minting, burning and transferring. + Resume { + /// Mint containing pausable configuration. + mint: crate::MdPubkey, + /// Current simple or multisig pause authority. + authority: crate::ExSplTokenAuthority, + }, + /// Initialize permissioned burn before mint initialization. + InitializePermissionedBurn { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Mandatory permissioned burn authority. + authority: crate::MdPubkey, + }, + /// Burn using both the permissioned authority and source owner/delegate. + PermissionedBurn { + /// Source token account. + source: crate::MdPubkey, + /// Token mint. + mint: crate::MdPubkey, + /// Dedicated permissioned burn authority signer. + permissioned_burn_authority: crate::MdPubkey, + /// Source owner/delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Raw amount to burn. + amount: crate::ExSplTokenAmount, + }, + /// Checked permissioned burn with exact mint decimals. + PermissionedBurnChecked { + /// Source token account. + source: crate::MdPubkey, + /// Token mint. + mint: crate::MdPubkey, + /// Dedicated permissioned burn authority signer. + permissioned_burn_authority: crate::MdPubkey, + /// Source owner/delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Raw amount to burn. + amount: crate::ExSplTokenAmount, + /// Expected mint decimals. + decimals: u8, + }, + /// Initialize Confidential Transfer configuration before mint initialization. + InitializeConfidentialTransferMint { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Optional authority for configuration updates and account approval. + authority: std::option::Option, + /// Whether newly configured accounts are approved automatically. + auto_approve_new_accounts: bool, + /// Optional caller-generated auditor ElGamal public key. + auditor_elgamal_pubkey: std::option::Option, + }, + /// Update Confidential Transfer mint configuration. + UpdateConfidentialTransferMint { + /// Mint containing the extension. + mint: crate::MdPubkey, + /// Current configuration authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Whether newly configured accounts are approved automatically. + auto_approve_new_accounts: bool, + /// Optional caller-generated auditor ElGamal public key. + auditor_elgamal_pubkey: std::option::Option, + }, + /// Apply pending confidential credits to the available balance. + ApplyPendingConfidentialBalance { + /// Token account whose pending credits are applied. + account: crate::MdPubkey, + /// Expected pending-balance credit counter. + expected_pending_balance_credit_counter: u64, + /// Caller-generated new decryptable available balance. + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance, + /// Owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Approve a configured account for confidential transfers. + ApproveConfidentialTransferAccount { + /// Token account to approve. + account: crate::MdPubkey, + /// Mint containing the confidential-transfer configuration. + mint: crate::MdPubkey, + /// Confidential-transfer mint authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Deposit a public token amount into the account confidential pending balance. + DepositConfidentialTokens { + /// Token account receiving the confidential pending credit. + account: crate::MdPubkey, + /// Token mint. + mint: crate::MdPubkey, + /// Owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Exact public amount deposited. + amount: crate::ExSplTokenAmount, + /// Expected mint decimals. + decimals: u8, + }, + /// Enable incoming confidential credits on a configured token account. + EnableConfidentialCredits { + /// Token account to update. + account: crate::MdPubkey, + /// Owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Disable incoming confidential credits on a configured token account. + DisableConfidentialCredits { + /// Token account to update. + account: crate::MdPubkey, + /// Owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Enable incoming non-confidential credits on a configured token account. + EnableNonConfidentialCredits { + /// Token account to update. + account: crate::MdPubkey, + /// Owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Disable incoming non-confidential credits on a configured token account. + DisableNonConfidentialCredits { + /// Token account to update. + account: crate::MdPubkey, + /// Owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Configure a confidential token account using a public-key validity proof reference. + ConfigureConfidentialTransferAccount { + /// Token account receiving the confidential extension. + account: crate::MdPubkey, + /// Corresponding Token-2022 mint. + mint: crate::MdPubkey, + /// Caller-generated decryptable zero balance. + decryptable_zero_balance: crate::ExSplTokenDecryptableBalance, + /// Maximum accepted pending-balance credit counter. + maximum_pending_balance_credit_counter: u64, + /// Owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Exact PubkeyValidity proof reference. + proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Configure a confidential token account through an ElGamal Registry account. + ConfigureConfidentialTransferAccountWithRegistry { + /// Token account receiving the confidential extension. + account: crate::MdPubkey, + /// Corresponding Token-2022 mint. + mint: crate::MdPubkey, + /// Valid ElGamal Registry PDA for the token-account owner. + registry_account: crate::MdPubkey, + /// Optional payer used only when the account must be reallocated. + payer: std::option::Option, + }, + /// Empty the confidential available-balance ciphertext before account close. + EmptyConfidentialTransferAccount { + /// Token account whose available confidential balance must already be zero. + account: crate::MdPubkey, + /// Owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Exact ZeroCiphertext proof reference. + proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Withdraw confidential available balance into the public token balance. + WithdrawConfidentialTokens { + /// Token account whose confidential available balance is debited. + account: crate::MdPubkey, + /// Token mint. + mint: crate::MdPubkey, + /// Exact raw amount withdrawn. + amount: crate::ExSplTokenAmount, + /// Expected mint decimals. + decimals: u8, + /// Caller-generated new decryptable available balance. + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance, + /// Owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Ciphertext-commitment equality proof reference. + equality_proof: crate::ExSplTokenConfidentialProofReference, + /// Batched U64 range proof reference. + range_proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Transfer confidential tokens between two Token-2022 accounts. + TransferConfidentialTokens { + /// Source token account whose confidential available balance is debited. + source: crate::MdPubkey, + /// Token mint. + mint: crate::MdPubkey, + /// Destination token account whose pending confidential balance is credited. + destination: crate::MdPubkey, + /// Caller-generated new source decryptable available balance. + new_source_decryptable_available_balance: crate::ExSplTokenDecryptableBalance, + /// Caller-generated lower auditor ciphertext component. + transfer_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext, + /// Caller-generated upper auditor ciphertext component. + transfer_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext, + /// Source owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Ciphertext-commitment equality proof reference. + equality_proof: crate::ExSplTokenConfidentialProofReference, + /// Batched grouped-ciphertext validity proof reference. + ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference, + /// Batched U128 range proof reference. + range_proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Transfer confidential tokens while applying the mint confidential transfer fee. + TransferConfidentialTokensWithFee { + /// Source token account whose confidential available balance is debited. + source: crate::MdPubkey, + /// Token mint. + mint: crate::MdPubkey, + /// Destination token account whose pending confidential balance is credited. + destination: crate::MdPubkey, + /// Caller-generated new source decryptable available balance. + new_source_decryptable_available_balance: crate::ExSplTokenDecryptableBalance, + /// Caller-generated lower auditor ciphertext component. + transfer_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext, + /// Caller-generated upper auditor ciphertext component. + transfer_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext, + /// Source owner or delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Ciphertext-commitment equality proof reference. + equality_proof: crate::ExSplTokenConfidentialProofReference, + /// Transfer-amount grouped-ciphertext validity proof reference. + transfer_amount_ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference, + /// Percentage-with-fee proof reference. + fee_sigma_proof: crate::ExSplTokenConfidentialProofReference, + /// Fee-ciphertext grouped-validity proof reference. + fee_ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference, + /// Batched U256 range proof reference. + range_proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Initialize confidential transfer fee configuration before mint initialization. + InitializeConfidentialTransferFeeConfig { + /// Mint receiving the extension. + mint: crate::MdPubkey, + /// Optional authority permitted to enable or disable harvest to mint. + authority: std::option::Option, + /// Caller-provided ElGamal public key used to encrypt withheld fees. + withdraw_withheld_authority_elgamal_pubkey: crate::ExSplTokenElGamalPubkey, + }, + /// Enable permissionless harvest of confidential withheld fees to the mint. + EnableConfidentialTransferFeeHarvest { + /// Mint containing confidential transfer fee configuration. + mint: crate::MdPubkey, + /// Current confidential transfer fee authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Disable permissionless harvest of confidential withheld fees to the mint. + DisableConfidentialTransferFeeHarvest { + /// Mint containing confidential transfer fee configuration. + mint: crate::MdPubkey, + /// Current confidential transfer fee authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Harvest confidential withheld fees from ordered token accounts to the mint. + HarvestConfidentialWithheldTokensToMint { + /// Mint receiving aggregated confidential withheld fees. + mint: crate::MdPubkey, + /// Ordered distinct source token accounts. + sources: std::vec::Vec, + }, + /// Withdraw all confidential withheld fees aggregated on the mint. + WithdrawConfidentialWithheldTokensFromMint { + /// Mint containing the aggregated confidential withheld ciphertext. + mint: crate::MdPubkey, + /// Confidential-transfer account receiving the withdrawn fees. + destination: crate::MdPubkey, + /// Caller-generated new decryptable available balance for the destination. + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance, + /// Mint withdraw-withheld authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Ciphertext-ciphertext equality proof reference. + proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Withdraw confidential withheld fees directly from ordered token accounts. + WithdrawConfidentialWithheldTokensFromAccounts { + /// Mint governing the confidential transfer fee configuration. + mint: crate::MdPubkey, + /// Confidential-transfer account receiving the withdrawn fees. + destination: crate::MdPubkey, + /// Caller-generated new decryptable available balance for the destination. + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance, + /// Mint withdraw-withheld authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Ordered distinct source token accounts. + sources: std::vec::Vec, + /// Ciphertext-ciphertext equality proof reference. + proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Initialize confidential mint and burn configuration before mint initialization. + InitializeConfidentialMintBurnMint { + /// Mint receiving the confidential mint-burn extension. + mint: crate::MdPubkey, + /// Caller-provided ElGamal public key used for confidential supply encryption. + supply_elgamal_pubkey: crate::ExSplTokenElGamalPubkey, + /// Caller-provided initial decryptable zero supply. + decryptable_supply: crate::ExSplTokenDecryptableBalance, + }, + /// Rotate the ElGamal public key used for confidential supply encryption. + RotateConfidentialSupplyElGamalPubkey { + /// Mint containing the confidential mint-burn extension. + mint: crate::MdPubkey, + /// New caller-provided supply ElGamal public key. + new_supply_elgamal_pubkey: crate::ExSplTokenElGamalPubkey, + /// Confidential mint authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Ciphertext-ciphertext equality proof reference. + proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Update the caller-decryptable confidential supply ciphertext. + UpdateConfidentialDecryptableSupply { + /// Mint containing the confidential mint-burn extension. + mint: crate::MdPubkey, + /// New caller-provided decryptable supply. + new_decryptable_supply: crate::ExSplTokenDecryptableBalance, + /// Confidential mint authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Apply the pending confidential burn ciphertext to the supply. + ApplyPendingConfidentialBurn { + /// Mint containing the confidential mint-burn extension. + mint: crate::MdPubkey, + /// Confidential mint authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + }, + /// Mint tokens directly into one confidential token account. + ConfidentialMint { + /// Confidential token account receiving the minted amount. + destination: crate::MdPubkey, + /// Mint containing the confidential mint-burn extension. + mint: crate::MdPubkey, + /// Caller-generated new decryptable confidential supply. + new_decryptable_supply: crate::ExSplTokenDecryptableBalance, + /// Mint amount ciphertext under the auditor key, low limb. + mint_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext, + /// Mint amount ciphertext under the auditor key, high limb. + mint_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext, + /// Confidential mint authority, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Ciphertext-commitment equality proof reference. + equality_proof: crate::ExSplTokenConfidentialProofReference, + /// Three-handle grouped-ciphertext validity proof reference. + ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference, + /// Batched U128 range proof reference. + range_proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Burn tokens directly from one confidential token account. + ConfidentialBurn { + /// Confidential token account supplying the burned amount. + source: crate::MdPubkey, + /// Mint containing the confidential mint-burn extension. + mint: crate::MdPubkey, + /// Caller-generated new decryptable available balance for the source. + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance, + /// Burn amount ciphertext under the auditor key, low limb. + burn_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext, + /// Burn amount ciphertext under the auditor key, high limb. + burn_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext, + /// Confidential account owner/delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Ciphertext-commitment equality proof reference. + equality_proof: crate::ExSplTokenConfidentialProofReference, + /// Three-handle grouped-ciphertext validity proof reference. + ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference, + /// Batched U128 range proof reference. + range_proof: crate::ExSplTokenConfidentialProofReference, + }, + /// Burn tokens from one confidential account with the mint permissioned-burn authority. + PermissionedConfidentialBurn { + /// Confidential token account supplying the burned amount. + source: crate::MdPubkey, + /// Mint containing Permissioned Burn and Confidential Mint/Burn extensions. + mint: crate::MdPubkey, + /// Permissioned-burn authority configured on the mint; always a direct signer. + permissioned_burn_authority: crate::MdPubkey, + /// Caller-generated new decryptable available balance for the source. + new_decryptable_available_balance: crate::ExSplTokenDecryptableBalance, + /// Burn amount ciphertext under the auditor key, low limb. + burn_amount_auditor_ciphertext_lo: crate::ExSplTokenElGamalCiphertext, + /// Burn amount ciphertext under the auditor key, high limb. + burn_amount_auditor_ciphertext_hi: crate::ExSplTokenElGamalCiphertext, + /// Confidential account owner/delegate, simple or multisig. + authority: crate::ExSplTokenAuthority, + /// Ciphertext-commitment equality proof reference. + equality_proof: crate::ExSplTokenConfidentialProofReference, + /// Three-handle grouped-ciphertext validity proof reference. + ciphertext_validity_proof: crate::ExSplTokenConfidentialProofReference, + /// Batched U128 range proof reference. + range_proof: crate::ExSplTokenConfidentialProofReference, + }, + /// 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::ExSplTokenAuthority, + /// Exact lamports to unwrap, or `None` for the complete balance. + amount_lamports: std::option::Option, + }, +} + +impl crate::ExSplTokenSingleOperation { + /// Returns the stable operation code. + pub fn operation_code(&self) -> &'static str { + return match self { + Self::InitializeMint { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION, + Self::InitializeAccount { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION, + Self::InitializeMultisig { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION, + Self::Transfer { .. } => crate::EX_SPL_TOKEN2022_TRANSFER_OPERATION, + Self::Approve { .. } => crate::EX_SPL_TOKEN2022_APPROVE_OPERATION, + Self::Revoke { .. } => crate::EX_SPL_TOKEN2022_REVOKE_OPERATION, + Self::SetAuthority { .. } => crate::EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION, + Self::MintTo { .. } => crate::EX_SPL_TOKEN2022_MINT_TO_OPERATION, + Self::Burn { .. } => crate::EX_SPL_TOKEN2022_BURN_OPERATION, + Self::CloseAccount { .. } => crate::EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION, + Self::FreezeAccount { .. } => crate::EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION, + Self::ThawAccount { .. } => crate::EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION, + Self::TransferChecked { .. } => crate::EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION, + Self::ApproveChecked { .. } => crate::EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION, + Self::MintToChecked { .. } => crate::EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION, + Self::BurnChecked { .. } => crate::EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION, + Self::SyncNative { .. } => crate::EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION, + Self::GetAccountDataSize { .. } => crate::EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION, + Self::InitializeImmutableOwner { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION, + Self::AmountToUiAmount { .. } => crate::EX_SPL_TOKEN2022_AMOUNT_TO_UI_AMOUNT_OPERATION, + Self::UiAmountToAmount { .. } => crate::EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION, + Self::WithdrawExcessLamports { .. } => crate::EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION, + Self::InitializeTransferFeeConfig { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION + }, + Self::SetTransferFee { .. } => crate::EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION, + Self::TransferCheckedWithFee { .. } => crate::EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION, + Self::WithdrawWithheldTokensFromMint { .. } => { + crate::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION + }, + Self::WithdrawWithheldTokensFromAccounts { .. } => { + crate::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION + }, + Self::HarvestWithheldTokensToMint { .. } => { + crate::EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION + }, + Self::InitializeDefaultAccountState { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION + }, + Self::UpdateDefaultAccountState { .. } => crate::EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION, + Self::EnableRequiredTransferMemos { .. } => { + crate::EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION + }, + Self::DisableRequiredTransferMemos { .. } => { + crate::EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION + }, + Self::EnableCpiGuard { .. } => crate::EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION, + Self::DisableCpiGuard { .. } => crate::EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION, + Self::InitializeTransferHook { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION, + Self::UpdateTransferHook { .. } => crate::EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION, + Self::InitializeMetadataPointer { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION, + Self::UpdateMetadataPointer { .. } => crate::EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION, + Self::InitializeGroupPointer { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION, + Self::UpdateGroupPointer { .. } => crate::EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION, + Self::InitializeGroupMemberPointer { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION + }, + Self::UpdateGroupMemberPointer { .. } => crate::EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION, + Self::InitializeTokenMetadata { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION, + Self::UpdateTokenMetadataField { .. } => crate::EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION, + Self::RemoveTokenMetadataKey { .. } => crate::EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION, + Self::InitializeTokenGroup { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION, + Self::UpdateTokenGroupMaxSize { .. } => crate::EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION, + Self::InitializeTokenGroupMember { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION + }, + Self::InitializeScaledUiAmount { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION, + Self::UpdateScaledUiAmountMultiplier { .. } => { + crate::EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION + }, + Self::InitializePausableConfig { .. } => crate::EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION, + Self::Pause { .. } => crate::EX_SPL_TOKEN2022_PAUSE_OPERATION, + Self::Resume { .. } => crate::EX_SPL_TOKEN2022_RESUME_OPERATION, + Self::InitializePermissionedBurn { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION + }, + Self::PermissionedBurn { .. } => crate::EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION, + Self::PermissionedBurnChecked { .. } => crate::EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION, + Self::InitializeConfidentialTransferMint { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION + }, + Self::UpdateConfidentialTransferMint { .. } => { + crate::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION + }, + Self::ApplyPendingConfidentialBalance { .. } => { + crate::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION + }, + Self::ApproveConfidentialTransferAccount { .. } => { + crate::EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION + }, + Self::DepositConfidentialTokens { .. } => crate::EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION, + Self::EnableConfidentialCredits { .. } => crate::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION, + Self::DisableConfidentialCredits { .. } => { + crate::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION + }, + Self::EnableNonConfidentialCredits { .. } => { + crate::EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION + }, + Self::DisableNonConfidentialCredits { .. } => { + crate::EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION + }, + Self::ConfigureConfidentialTransferAccount { .. } => { + crate::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION + }, + Self::ConfigureConfidentialTransferAccountWithRegistry { .. } => { + crate::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION + }, + Self::EmptyConfidentialTransferAccount { .. } => { + crate::EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION + }, + Self::WithdrawConfidentialTokens { .. } => { + crate::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION + }, + Self::TransferConfidentialTokens { .. } => { + crate::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION + }, + Self::TransferConfidentialTokensWithFee { .. } => { + crate::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION + }, + Self::InitializeConfidentialTransferFeeConfig { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION + }, + Self::EnableConfidentialTransferFeeHarvest { .. } => { + crate::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION + }, + Self::DisableConfidentialTransferFeeHarvest { .. } => { + crate::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION + }, + Self::HarvestConfidentialWithheldTokensToMint { .. } => { + crate::EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION + }, + Self::WithdrawConfidentialWithheldTokensFromMint { .. } => { + crate::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION + }, + Self::WithdrawConfidentialWithheldTokensFromAccounts { .. } => { + crate::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION + }, + Self::InitializeConfidentialMintBurnMint { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION + }, + Self::RotateConfidentialSupplyElGamalPubkey { .. } => { + crate::EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION + }, + Self::UpdateConfidentialDecryptableSupply { .. } => { + crate::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION + }, + Self::ApplyPendingConfidentialBurn { .. } => { + crate::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION + }, + Self::ConfidentialMint { .. } => crate::EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION, + Self::ConfidentialBurn { .. } => crate::EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION, + Self::PermissionedConfidentialBurn { .. } => { + crate::EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION + }, + Self::UnwrapLamports { .. } => crate::EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION, + Self::Reallocate { .. } => crate::EX_SPL_TOKEN2022_REALLOCATE_OPERATION, + Self::InitializeNonTransferableMint { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION + }, + Self::InitializePermanentDelegate { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION + }, + Self::InitializeInterestBearingMint { .. } => { + crate::EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION + }, + Self::UpdateInterestBearingRate { .. } => crate::EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_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_executor_spl_token_2022/intent/ExSplToken2022Operation.ts" +)] +pub enum ExSplToken2022Operation { + /// Build one non-batch instruction. + Instruction { + /// Exact instruction arguments. + value: std::boxed::Box, + }, + /// Build one Batch from ordered, non-batch child operations. + Batch { + /// Ordered child operations. Nested Batch is impossible in this contract. + instructions: std::vec::Vec, + }, +} + +impl crate::ExSplToken2022Operation { + /// 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_TOKEN2022_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 Token-2022 executor. +#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplToken2022ExecutionIntent.ts" +)] +pub struct ExSplToken2022ExecutionIntent { + /// 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::ExSplToken2022Operation, +} diff --git a/kb-lib/src/lib.rs b/kb-lib/src/lib.rs index 4092a37..c1c35a4 100644 --- a/kb-lib/src/lib.rs +++ b/kb-lib/src/lib.rs @@ -1,5 +1,5 @@ // file: kb-lib/src/lib.rs -// version: 20 +// version: 21 //! Consolidated decoder, executor, materializer and shared model library. #![warn(missing_docs)] @@ -577,6 +577,206 @@ pub use self::executor::EX_SPL_MEMO_ADD_MEMO_OPERATION; pub use self::executor::EX_SPL_MEMO_MAX_MESSAGE_BYTES; /// Exposes the SPL Memo signer bound. pub use self::executor::EX_SPL_MEMO_MAX_SIGNERS; +/// Exposes `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`. +pub use self::executor::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_APPROVE_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_APPROVE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_APPROVE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BATCH_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_BATCH_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_BURN_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_BURN_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_CLOSE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_CONFIDENTIAL_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG`. +pub use self::executor::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_EXTERNAL_TAG; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES`. +pub use self::executor::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES`. +pub use self::executor::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES; +/// Exposes `EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG`. +pub use self::executor::EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG; +/// Exposes `EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES`. +pub use self::executor::EX_SPL_TOKEN2022_DECRYPTABLE_BALANCE_BYTES; +/// Exposes `EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_DISABLE_CPI_GUARD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES`. +pub use self::executor::EX_SPL_TOKEN2022_ELGAMAL_CIPHERTEXT_BYTES; +/// Exposes `EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES`. +pub use self::executor::EX_SPL_TOKEN2022_ELGAMAL_PUBKEY_BYTES; +/// Exposes `EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_ENABLE_CPI_GUARD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_FREEZE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_GET_ACCOUNT_DATA_SIZE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_GROUP_MEMBER_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_GROUP_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_IMMUTABLE_OWNER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_INTEREST_BEARING_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_METADATA_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_MULTISIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_PAUSABLE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_PERMANENT_DELEGATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_PERMISSIONED_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_SCALED_UI_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_GROUP_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_TOKEN_METADATA_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_INITIALIZE_TRANSFER_HOOK_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES`. +pub use self::executor::EX_SPL_TOKEN2022_MAX_CONFIDENTIAL_PROOF_REFERENCES; +/// Exposes `EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_MINT_TO_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_MINT_TO_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_MINT_TO_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PAUSE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_PAUSE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_PERMISSIONED_BURN_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_PERMISSIONED_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_PERMISSIONED_CONFIDENTIAL_BURN_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REALLOCATE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_REALLOCATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_REMOVE_TOKEN_METADATA_KEY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_RESUME_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_RESUME_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_REVOKE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_REVOKE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_SET_AUTHORITY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_SET_TRANSFER_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES`. +pub use self::executor::EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES; +/// Exposes `EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_SYNC_NATIVE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_THAW_ACCOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_TRANSFER_CHECKED_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_TRANSFER_CHECKED_WITH_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_TRANSFER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_TRANSFER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UI_AMOUNT_TO_AMOUNT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UNWRAP_LAMPORTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_GROUP_MEMBER_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_GROUP_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_INTEREST_BEARING_RATE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_METADATA_POINTER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_UPDATE_TRANSFER_HOOK_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_WITHDRAW_EXCESS_LAMPORTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION; +/// Exposes `EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION`. +pub use self::executor::EX_SPL_TOKEN2022_WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION; /// Exposes the reserved `ExAdapterSaberDecimalWrapperExecutor` implementation. pub use self::executor::ExAdapterSaberDecimalWrapperExecutor; /// Exposes the reserved `ExAdminJupiterLockExecutor` implementation. @@ -841,10 +1041,46 @@ pub use self::executor::ExSplNoopExecutor; pub use self::executor::ExSplSinglePoolExecutor; /// Exposes the reserved `ExSplStakePoolExecutor` implementation. pub use self::executor::ExSplStakePoolExecutor; -/// Exposes the reserved `ExSplToken2022Executor` implementation. +/// Exposes `ExSplToken2022ExecutionIntent`. +pub use self::executor::ExSplToken2022ExecutionIntent; +/// Exposes `ExSplToken2022Executor`. pub use self::executor::ExSplToken2022Executor; +/// Exposes `ExSplToken2022Operation`. +pub use self::executor::ExSplToken2022Operation; +/// Exposes `ExSplTokenAmount`. +pub use self::executor::ExSplTokenAmount; +/// Exposes `ExSplTokenAuthority`. +pub use self::executor::ExSplTokenAuthority; +/// Exposes `ExSplTokenAuthorityType`. +pub use self::executor::ExSplTokenAuthorityType; +/// Exposes `ExSplTokenConfidentialExecutorSupport`. +pub use self::executor::ExSplTokenConfidentialExecutorSupport; +/// Exposes `ExSplTokenConfidentialMintBurnOperation`. +pub use self::executor::ExSplTokenConfidentialMintBurnOperation; +/// Exposes `ExSplTokenConfidentialOperation`. +pub use self::executor::ExSplTokenConfidentialOperation; +/// Exposes `ExSplTokenConfidentialProofKind`. +pub use self::executor::ExSplTokenConfidentialProofKind; +/// Exposes `ExSplTokenConfidentialProofLocation`. +pub use self::executor::ExSplTokenConfidentialProofLocation; +/// Exposes `ExSplTokenConfidentialProofReference`. +pub use self::executor::ExSplTokenConfidentialProofReference; +/// Exposes `ExSplTokenDecryptableBalance`. +pub use self::executor::ExSplTokenDecryptableBalance; +/// Exposes `ExSplTokenDefaultAccountState`. +pub use self::executor::ExSplTokenDefaultAccountState; +/// Exposes `ExSplTokenElGamalCiphertext`. +pub use self::executor::ExSplTokenElGamalCiphertext; +/// Exposes `ExSplTokenElGamalPubkey`. +pub use self::executor::ExSplTokenElGamalPubkey; /// Exposes the reserved `ExSplTokenExecutor` implementation. pub use self::executor::ExSplTokenExecutor; +/// Exposes `ExSplTokenMetadataField`. +pub use self::executor::ExSplTokenMetadataField; +/// Exposes `ExSplTokenMultiplier`. +pub use self::executor::ExSplTokenMultiplier; +/// Exposes `ExSplTokenSingleOperation`. +pub use self::executor::ExSplTokenSingleOperation; /// Exposes the reserved `ExStableSwapHyloExchangeExecutor` implementation. pub use self::executor::ExStableSwapHyloExchangeExecutor; /// Exposes the reserved `ExStableSwapJupiterStableExecutor` implementation. @@ -883,6 +1119,8 @@ pub use self::executor::ExWeightedSwapStabbleExecutor; pub use self::executor::executor_api_serialize_payload_json; /// Exposes the pretty JSON payload serializer. pub use self::executor::executor_api_serialize_payload_json_pretty; +/// Exposes `executor_spl_token2022_validate_confidential_proof_references`. +pub use self::executor::executor_spl_token2022_validate_confidential_proof_references; /// Stable native and SPL administration materializer. pub use self::materializer::MtAdminMaterializer; /// Stable decoded observation materializer contract used by the common pipeline. @@ -1452,6 +1690,14 @@ pub(crate) use self::executor::EX_SOLANA_CORE_TRACING_TARGET; pub(crate) use self::executor::EX_SPL_ATA_TRACING_TARGET; /// Canonical SPL Memo tracing target. pub(crate) use self::executor::EX_SPL_MEMO_TRACING_TARGET; +/// Maximum ordered multisig signer occurrences for SPL Token-2022. +pub(crate) use self::executor::EX_SPL_TOKEN2022_MAX_MULTISIG_SIGNERS; +/// Maximum transfer-fee source account count for SPL Token-2022. +pub(crate) use self::executor::EX_SPL_TOKEN2022_MAX_TRANSFER_FEE_SOURCE_ACCOUNTS; +/// Maximum UI amount byte length for SPL Token-2022. +pub(crate) use self::executor::EX_SPL_TOKEN2022_MAX_UI_AMOUNT_BYTES; +/// Canonical SPL Token-2022 tracing target. +pub(crate) use self::executor::EX_SPL_TOKEN2022_TRACING_TARGET; /// Crate-root access to `build_prepared_plan` from `address_lookup_table`. pub(crate) use self::executor::executor_solana_core_address_lookup_table_build_prepared_plan; /// Crate-root access to `build_prepared_plan` from `builder`. @@ -1492,6 +1738,8 @@ pub(crate) use self::executor::executor_solana_core_zk_elgamal_build_prepared_pl pub(crate) use self::executor::executor_spl_ata_build_prepared_plan; /// Internal SPL Memo plan builder. pub(crate) use self::executor::executor_spl_memo_build_prepared_plan; +/// Internal SPL Token-2022 prepared-plan builder. +pub(crate) use self::executor::executor_spl_token2022_build_prepared_plan; /// Canonical processor name for the native and SPL administration materializer. pub(crate) use self::materializer::MT_ADMIN_PROCESSOR_NAME; /// Canonical tracing target for the native and SPL administration materializer. diff --git a/kb-lib/src/model/nomenclature.rs b/kb-lib/src/model/nomenclature.rs index 973909e..505865c 100644 --- a/kb-lib/src/model/nomenclature.rs +++ b/kb-lib/src/model/nomenclature.rs @@ -1,5 +1,5 @@ // file: kb-lib/src/model/nomenclature.rs -// version: 4 +// version: 5 //! Shared protocol, surface, and event nomenclature types. @@ -31,12 +31,18 @@ pub struct MdSurfaceCode(pub std::string::String); /// Event name without surface prefix. #[derive(Clone, Debug, Eq, PartialEq, Hash, serde::Deserialize, serde::Serialize, TS)] -#[ts(export, export_to = "../frontend/ts/bindings/kb_lib/model/nomenclature/EventName.ts")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_lib/model/nomenclature/EventName.ts" +)] pub struct MdEventName(pub std::string::String); /// Canonical event code in `.` format. #[derive(Clone, Debug, Eq, PartialEq, Hash, serde::Deserialize, serde::Serialize, TS)] -#[ts(export, export_to = "../frontend/ts/bindings/kb_lib/model/nomenclature/EventCode.ts")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_lib/model/nomenclature/EventCode.ts" +)] pub struct MdEventCode(pub std::string::String); /// High-level event family. diff --git a/kb-lib/src/model/solana.rs b/kb-lib/src/model/solana.rs index 48719d2..2615cdd 100644 --- a/kb-lib/src/model/solana.rs +++ b/kb-lib/src/model/solana.rs @@ -1,5 +1,5 @@ // file: kb-lib/src/model/solana.rs -// version: 4 +// version: 5 //! Shared Solana primitive wrapper types. @@ -39,5 +39,8 @@ pub struct MdPubkey(pub std::string::String); /// Stable top-level or inner instruction path. #[derive(Clone, Debug, Eq, PartialEq, Hash, serde::Deserialize, serde::Serialize, TS)] -#[ts(export, export_to = "../frontend/ts/bindings/kb_lib/model/solana/InstructionPath.ts")] +#[ts( + export, + export_to = "../frontend/ts/bindings/kb_lib/model/solana/InstructionPath.ts" +)] pub struct MdInstructionPath(pub std::string::String); diff --git a/scripts/audit_khadhroony_workspace_rules.py b/scripts/audit_khadhroony_workspace_rules.py index fae0d20..2bae1d1 100755 --- a/scripts/audit_khadhroony_workspace_rules.py +++ b/scripts/audit_khadhroony_workspace_rules.py @@ -438,13 +438,13 @@ def audit_reserved_executor_scaffolds(root: pathlib.Path) -> list[Violation]: "reserved executor must build only an explicit zero-instruction plan", ) ) - if reserved_count != 101: + if reserved_count != 100: violations.append( Violation( "KH_EX007", "kb-lib/src/executor", 1, - f"expected 101 reserved executor boundaries, found {reserved_count}", + f"expected 100 reserved executor boundaries, found {reserved_count}", ) ) return violations