This commit is contained in:
2026-07-23 16:37:12 +02:00
parent 99c345f2f2
commit 0da75c1311
2159 changed files with 230833 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,576 @@
// file: kb_executor_spl_token_2022/src/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 MAX_CONFIDENTIAL_PROOF_REFERENCES: usize = 5;
/// Exact byte length of an ElGamal public key accepted from callers.
pub const ELGAMAL_PUBKEY_BYTES: usize = 32;
/// Exact byte length of one decryptable authenticated balance ciphertext.
pub const DECRYPTABLE_BALANCE_BYTES: usize = 36;
/// Exact byte length of one ElGamal ciphertext accepted from callers.
pub const ELGAMAL_CIPHERTEXT_BYTES: usize = 64;
/// Token-2022 outer tag shared by all Confidential Transfer instructions.
pub const CONFIDENTIAL_TRANSFER_EXTERNAL_TAG: u8 = 27;
/// Confidential Transfer subtag published for `TransferWithFee`.
pub const CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG: u8 = 13;
/// Exact payload bytes after the two instruction discriminants for `TransferWithFee`.
pub const CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES: usize =
DECRYPTABLE_BALANCE_BYTES + (ELGAMAL_CIPHERTEXT_BYTES * 2) + MAX_CONFIDENTIAL_PROOF_REFERENCES;
/// Exact total Token-2022 instruction-data bytes for `TransferWithFee`.
pub const CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES: usize =
2 + 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/SplTokenElGamalPubkey.ts"
)]
pub struct SplTokenElGamalPubkey(pub std::string::String);
impl SplTokenElGamalPubkey {
pub(crate) fn parse(
&self,
) -> Result<solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, std::string::String> {
let bytes = match decode_exact_hex(&self.0, ELGAMAL_PUBKEY_BYTES, "ElGamal public key") {
Ok(value) => value,
Err(error) => return Err(error),
};
let array = match <[u8; 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/SplTokenDecryptableBalance.ts"
)]
pub struct SplTokenDecryptableBalance(pub std::string::String);
impl SplTokenDecryptableBalance {
pub(crate) fn parse(
&self,
) -> Result<solana_zk_sdk_pod::encryption::auth_encryption::PodAeCiphertext, std::string::String>
{
let bytes =
match decode_exact_hex(&self.0, DECRYPTABLE_BALANCE_BYTES, "decryptable balance") {
Ok(value) => value,
Err(error) => return Err(error),
};
let array = match <[u8; 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/SplTokenElGamalCiphertext.ts"
)]
pub struct SplTokenElGamalCiphertext(pub std::string::String);
impl SplTokenElGamalCiphertext {
pub(crate) fn parse(
&self,
) -> Result<solana_zk_sdk_pod::encryption::elgamal::PodElGamalCiphertext, std::string::String>
{
let bytes = match decode_exact_hex(&self.0, ELGAMAL_CIPHERTEXT_BYTES, "ElGamal ciphertext")
{
Ok(value) => value,
Err(error) => return Err(error),
};
let array = match <[u8; 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::vec::Vec<u8>, 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<u8> {
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/SplTokenConfidentialProofKind.ts"
)]
pub enum SplTokenConfidentialProofKind {
/// 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/SplTokenConfidentialProofLocation.ts"
)]
pub enum SplTokenConfidentialProofLocation {
/// 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: kb_model::Pubkey,
},
}
impl SplTokenConfidentialProofLocation {
/// 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/SplTokenConfidentialProofReference.ts"
)]
pub struct SplTokenConfidentialProofReference {
/// Exact proof statement required by the Token-2022 builder.
pub kind: SplTokenConfidentialProofKind,
/// Inline-instruction or context-state source.
pub location: SplTokenConfidentialProofLocation,
}
/// 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/SplTokenConfidentialOperation.ts"
)]
pub enum SplTokenConfidentialOperation {
/// 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 SplTokenConfidentialOperation {
/// Returns the ordered proof statements required by the official builder.
pub fn required_proofs(&self) -> &'static [SplTokenConfidentialProofKind] {
return match self {
Self::ConfigureAccount | Self::ConfigureAccountWithRegistry => {
&[SplTokenConfidentialProofKind::PubkeyValidity]
},
Self::EmptyAccount => &[SplTokenConfidentialProofKind::ZeroCiphertext],
Self::Withdraw => &[
SplTokenConfidentialProofKind::CiphertextCommitmentEquality,
SplTokenConfidentialProofKind::BatchedRangeProofU64,
],
Self::Transfer => &[
SplTokenConfidentialProofKind::CiphertextCommitmentEquality,
SplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity,
SplTokenConfidentialProofKind::BatchedRangeProofU128,
],
Self::TransferWithFee => &[
SplTokenConfidentialProofKind::CiphertextCommitmentEquality,
SplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity,
SplTokenConfidentialProofKind::PercentageWithFee,
SplTokenConfidentialProofKind::BatchedGroupedCiphertext2HandlesValidity,
SplTokenConfidentialProofKind::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) -> SplTokenConfidentialExecutorSupport {
return match self {
Self::InitializeMint
| Self::UpdateMint
| Self::ApproveAccount
| Self::Deposit
| Self::ApplyPendingBalance
| Self::EnableConfidentialCredits
| Self::DisableConfidentialCredits
| Self::EnableNonConfidentialCredits
| Self::DisableNonConfidentialCredits => {
SplTokenConfidentialExecutorSupport::PublicBuilderReady
},
Self::ConfigureAccount
| Self::EmptyAccount
| Self::Withdraw
| Self::Transfer
| Self::TransferWithFee
| Self::ConfigureAccountWithRegistry => {
SplTokenConfidentialExecutorSupport::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/SplTokenConfidentialMintBurnOperation.ts"
)]
pub enum SplTokenConfidentialMintBurnOperation {
/// 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 SplTokenConfidentialMintBurnOperation {
/// 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 [SplTokenConfidentialProofKind] {
return match self {
Self::RotateSupplyElGamalPubkey => {
&[SplTokenConfidentialProofKind::CiphertextCiphertextEquality]
},
Self::Mint | Self::Burn => &[
SplTokenConfidentialProofKind::CiphertextCommitmentEquality,
SplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity,
SplTokenConfidentialProofKind::BatchedRangeProofU128,
],
Self::InitializeMint | Self::UpdateDecryptableSupply | Self::ApplyPendingBurn => &[],
};
}
/// Classifies whether the caller must supply cryptographic material.
pub fn executor_support(&self) -> SplTokenConfidentialExecutorSupport {
return match self {
Self::UpdateDecryptableSupply | Self::ApplyPendingBurn => {
SplTokenConfidentialExecutorSupport::PublicBuilderReady
},
Self::InitializeMint | Self::RotateSupplyElGamalPubkey | Self::Mint | Self::Burn => {
SplTokenConfidentialExecutorSupport::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/SplTokenConfidentialExecutorSupport.ts"
)]
pub enum SplTokenConfidentialExecutorSupport {
/// 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 validate_confidential_proof_references(
operation: SplTokenConfidentialOperation,
references: &[SplTokenConfidentialProofReference],
) -> Result<(), std::string::String> {
let required = operation.required_proofs();
if references.len() > 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::SplTokenConfidentialOperation::Deposit.executor_support(),
super::SplTokenConfidentialExecutorSupport::PublicBuilderReady
);
assert_eq!(
super::SplTokenConfidentialOperation::Transfer.executor_support(),
super::SplTokenConfidentialExecutorSupport::RequiresCallerGeneratedCryptographicInputs
);
assert_eq!(
super::SplTokenConfidentialOperation::ConfigureAccountWithRegistry.executor_support(),
super::SplTokenConfidentialExecutorSupport::RequiresCallerGeneratedCryptographicInputs
);
}
#[test]
fn opaque_public_inputs_require_exact_hex_lengths() {
let pubkey = super::SplTokenElGamalPubkey("11".repeat(super::ELGAMAL_PUBKEY_BYTES));
assert!(pubkey.parse().is_ok());
let balance =
super::SplTokenDecryptableBalance("22".repeat(super::DECRYPTABLE_BALANCE_BYTES));
assert!(balance.parse().is_ok());
assert!(super::SplTokenElGamalPubkey("00".repeat(31)).parse().is_err());
assert!(super::SplTokenDecryptableBalance("zz".repeat(36)).parse().is_err());
let ciphertext =
super::SplTokenElGamalCiphertext("33".repeat(super::ELGAMAL_CIPHERTEXT_BYTES));
assert!(ciphertext.parse().is_ok());
assert!(super::SplTokenElGamalCiphertext("33".repeat(63)).parse().is_err());
}
#[test]
fn proof_inventory_preserves_official_transfer_and_fee_order() {
assert_eq!(
super::SplTokenConfidentialOperation::Transfer.required_proofs(),
&[
super::SplTokenConfidentialProofKind::CiphertextCommitmentEquality,
super::SplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity,
super::SplTokenConfidentialProofKind::BatchedRangeProofU128,
]
);
assert_eq!(
super::SplTokenConfidentialOperation::TransferWithFee.required_proofs(),
&[
super::SplTokenConfidentialProofKind::CiphertextCommitmentEquality,
super::SplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity,
super::SplTokenConfidentialProofKind::PercentageWithFee,
super::SplTokenConfidentialProofKind::BatchedGroupedCiphertext2HandlesValidity,
super::SplTokenConfidentialProofKind::BatchedRangeProofU256,
]
);
}
#[test]
fn transfer_with_fee_audit_matches_official_wire_and_requires_no_extra_token_payload_ciphertext()
{
assert_eq!(super::CONFIDENTIAL_TRANSFER_EXTERNAL_TAG, 27);
assert_eq!(super::CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG, 13);
assert_eq!(super::CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES, 169);
assert_eq!(super::CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES, 171);
assert_eq!(
core::mem::size_of::<
spl_token_2022_interface::extension::confidential_transfer::instruction::TransferWithFeeInstructionData,
>(),
super::CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES
);
assert_eq!(
super::SplTokenConfidentialOperation::TransferWithFee.required_proofs().len(),
super::MAX_CONFIDENTIAL_PROOF_REFERENCES
);
let decryptable_balance =
super::SplTokenDecryptableBalance("44".repeat(super::DECRYPTABLE_BALANCE_BYTES));
let auditor_ciphertext_lo =
super::SplTokenElGamalCiphertext("55".repeat(super::ELGAMAL_CIPHERTEXT_BYTES));
let auditor_ciphertext_hi =
super::SplTokenElGamalCiphertext("66".repeat(super::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::SplTokenConfidentialMintBurnOperation::InitializeMint.subtag(), 0);
assert_eq!(
super::SplTokenConfidentialMintBurnOperation::RotateSupplyElGamalPubkey.subtag(),
1
);
assert_eq!(
super::SplTokenConfidentialMintBurnOperation::UpdateDecryptableSupply.subtag(),
2
);
assert_eq!(super::SplTokenConfidentialMintBurnOperation::Mint.subtag(), 3);
assert_eq!(super::SplTokenConfidentialMintBurnOperation::Burn.subtag(), 4);
assert_eq!(super::SplTokenConfidentialMintBurnOperation::ApplyPendingBurn.subtag(), 5);
assert_eq!(
super::SplTokenConfidentialMintBurnOperation::RotateSupplyElGamalPubkey
.required_proofs(),
&[super::SplTokenConfidentialProofKind::CiphertextCiphertextEquality]
);
assert_eq!(
super::SplTokenConfidentialMintBurnOperation::Mint.required_proofs(),
&[
super::SplTokenConfidentialProofKind::CiphertextCommitmentEquality,
super::SplTokenConfidentialProofKind::BatchedGroupedCiphertext3HandlesValidity,
super::SplTokenConfidentialProofKind::BatchedRangeProofU128,
]
);
assert_eq!(
super::SplTokenConfidentialMintBurnOperation::Burn.required_proofs(),
super::SplTokenConfidentialMintBurnOperation::Mint.required_proofs()
);
assert_eq!(
super::SplTokenConfidentialMintBurnOperation::ApplyPendingBurn.executor_support(),
super::SplTokenConfidentialExecutorSupport::PublicBuilderReady
);
assert_eq!(
super::SplTokenConfidentialMintBurnOperation::Mint.executor_support(),
super::SplTokenConfidentialExecutorSupport::RequiresCallerGeneratedCryptographicInputs
);
}
#[test]
fn proof_locations_keep_inline_and_context_state_modes_unambiguous() {
let context_account = kb_model::Pubkey("11111111111111111111111111111111".to_owned());
let references = vec![super::SplTokenConfidentialProofReference {
kind: super::SplTokenConfidentialProofKind::ZeroCiphertext,
location: super::SplTokenConfidentialProofLocation::ContextStateAccount {
account: context_account,
},
}];
assert!(
super::validate_confidential_proof_references(
super::SplTokenConfidentialOperation::EmptyAccount,
&references
)
.is_ok()
);
let invalid = vec![super::SplTokenConfidentialProofReference {
kind: super::SplTokenConfidentialProofKind::ZeroCiphertext,
location: super::SplTokenConfidentialProofLocation::InstructionOffset { offset: 0 },
}];
assert!(
super::validate_confidential_proof_references(
super::SplTokenConfidentialOperation::EmptyAccount,
&invalid
)
.is_err()
);
}
}

View File

@@ -0,0 +1,13 @@
// file: kb_executor_spl_token_2022/src/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 MAX_MULTISIG_SIGNERS: usize = 11;
/// Maximum UI amount string length accepted before transaction assembly.
pub(crate) const MAX_UI_AMOUNT_BYTES: usize = 255;
/// Maximum ordered token accounts accepted by transfer-fee harvest or withdraw builders.
pub(crate) const MAX_TRANSFER_FEE_SOURCE_ACCOUNTS: usize = 255;
/// Canonical tracing target for this crate.
pub(crate) const TRACING_TARGET: &str = "kb_executor_spl_token_2022";

View File

@@ -0,0 +1,332 @@
// file: kb_executor_spl_token_2022/src/executor.rs
// version: 19
//! Exact Token-2022 capability dispatch and typed plan construction.
/// Token-2022 executor implementation.
#[derive(Clone, Debug, Default)]
pub struct SplToken2022Executor;
impl crate::SplToken2022Executor {
fn exact_capability(
&self,
program_id: &kb_model::ProgramId,
operation_code: &str,
) -> kb_execution_api::ExecutionCapability {
if program_id.0 != kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID {
return kb_execution_api::ExecutionCapability::unsupported(
"execution_spl_token_2022_program_not_owned",
format!("program {} is not owned by kb_executor_spl_token_2022", program_id.0),
);
}
if crate::SUPPORTED_OPERATION_CODES.contains(&operation_code) {
return kb_execution_api::ExecutionCapability::supported(operation_code);
}
if operation_code == crate::BATCH_OPERATION {
return kb_execution_api::ExecutionCapability::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 kb_execution_api::ExecutionCapability::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 kb_execution_api::ExecutionCapability::unsupported(
"execution_spl_token_2022_operation_unsupported",
format!("SPL Token operation {operation_code} is not implemented"),
);
}
}
impl kb_execution_api::TypedInstructionExecutor for crate::SplToken2022Executor {
type Intent = crate::SplToken2022ExecutionIntent;
fn capability(
&self,
program_id: &kb_model::ProgramId,
operation_code: &str,
) -> kb_execution_api::ExecutionCapability {
return self.exact_capability(program_id, operation_code);
}
fn build_prepared_plan(
&self,
intent: &Self::Intent,
) -> kb_core::Result<kb_execution_api::PreparedExecutionPlan> {
let program_id = kb_model::ProgramId(std::string::String::from(
kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID,
));
return match self.exact_capability(&program_id, intent.operation.operation_code()) {
kb_execution_api::ExecutionCapability::Supported { operation_code: _ } => {
crate::build_prepared_plan(intent)
},
kb_execution_api::ExecutionCapability::Unsupported { reason_code, reason } => {
std::result::Result::Err(kb_core::Error::new(reason_code, reason))
},
};
}
}
impl kb_execution_api::InstructionExecutor for crate::SplToken2022Executor {
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_TOKEN_2022_PROGRAM_ID];
}
fn supports_request(
&self,
request: &kb_execution_api::ExecutionRequest,
) -> kb_execution_api::ExecutionSupport {
return match self.exact_capability(&request.program_id, &request.operation_code) {
kb_execution_api::ExecutionCapability::Supported { operation_code: _ } => {
kb_execution_api::ExecutionSupport::Yes
},
kb_execution_api::ExecutionCapability::Unsupported { reason_code: _, reason: _ } => {
kb_execution_api::ExecutionSupport::No
},
};
}
fn build_plan(
&self,
request: &kb_execution_api::ExecutionRequest,
) -> kb_core::Result<kb_execution_api::ExecutionPlan> {
match self.exact_capability(&request.program_id, &request.operation_code) {
kb_execution_api::ExecutionCapability::Supported { operation_code: _ } => {},
kb_execution_api::ExecutionCapability::Unsupported { reason_code, reason } => {
return std::result::Result::Err(kb_core::Error::new(reason_code, reason));
},
}
let intent =
match serde_json::from_str::<crate::SplToken2022ExecutionIntent>(&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 kb_execution_api::TypedInstructionExecutor::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 kb_execution_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(kb_execution_api::ExecutionPlan {
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) -> kb_execution_api::ExecutionRequest {
return kb_execution_api::ExecutionRequest {
program_id: kb_model::ProgramId(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::SplToken2022Executor;
for operation_code in crate::SUPPORTED_OPERATION_CODES {
let request = request(kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID, operation_code);
assert_eq!(
kb_execution_api::InstructionExecutor::supports_request(&executor, &request),
kb_execution_api::ExecutionSupport::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 = kb_execution_api::TypedInstructionExecutor::capability(
&executor,
&kb_model::ProgramId(kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID.to_string()),
operation_code,
);
match capability {
kb_execution_api::ExecutionCapability::Unsupported { reason_code, reason: _ } => {
assert_eq!(
reason_code,
"execution_spl_token_2022_historical_variant_decode_only"
);
},
kb_execution_api::ExecutionCapability::Supported { operation_code: _ } => {
panic!("historical variant must be decode-only");
},
}
}
}
#[test]
fn program_dispatch_is_exact() {
let executor = crate::SplToken2022Executor;
let foreign =
request(kb_program_ids::SPL_TOKEN_PROGRAM_ID, crate::TRANSFER_CHECKED_OPERATION);
assert_eq!(
kb_execution_api::InstructionExecutor::supports_request(&executor, &foreign),
kb_execution_api::ExecutionSupport::No
);
}
#[test]
fn machine_readable_matrix_matches_executor_policy() {
let matrix = serde_json::from_str::<serde_json::Value>(include_str!(
"../../docs/SPL_TOKEN_2022_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::<std::collections::BTreeSet<_>>();
assert_eq!(instructions.len(), 48);
for operation_code in crate::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 = kb_execution_api::TypedInstructionExecutor::capability(
&crate::SplToken2022Executor,
&kb_model::ProgramId(kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID.to_string()),
crate::BATCH_OPERATION,
);
match batch {
kb_execution_api::ExecutionCapability::Unsupported { reason_code, reason: _ } => {
assert_eq!(reason_code, "execution_spl_token_2022_batch_builder_unavailable");
},
kb_execution_api::ExecutionCapability::Supported { operation_code: _ } => {
panic!("Batch must remain decode-only");
},
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,265 @@
// file: kb_executor_spl_token_2022/src/lib.rs
// version: 27
//! Executor crate for `spl_token_2022`.
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
mod builder;
mod confidential;
mod constants;
mod executor;
mod intent;
/// Crate-root access to `build_prepared_plan` from `builder`.
pub(crate) use crate::builder::build_prepared_plan;
/// Maximum number of ordered multisig signer occurrences.
pub(crate) use crate::constants::MAX_MULTISIG_SIGNERS;
/// Maximum ordered token accounts accepted by transfer-fee harvest or withdraw builders.
pub(crate) use crate::constants::MAX_TRANSFER_FEE_SOURCE_ACCOUNTS;
/// Maximum UI amount string length accepted before transaction assembly.
pub(crate) use crate::constants::MAX_UI_AMOUNT_BYTES;
/// Canonical tracing target for this crate.
pub(crate) use crate::constants::TRACING_TARGET;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::CONFIDENTIAL_TRANSFER_EXTERNAL_TAG;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::CONFIDENTIAL_TRANSFER_WITH_FEE_PAYLOAD_BYTES;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::CONFIDENTIAL_TRANSFER_WITH_FEE_SUBTAG;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::DECRYPTABLE_BALANCE_BYTES;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::ELGAMAL_CIPHERTEXT_BYTES;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::ELGAMAL_PUBKEY_BYTES;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::MAX_CONFIDENTIAL_PROOF_REFERENCES;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::SplTokenConfidentialExecutorSupport;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::SplTokenConfidentialMintBurnOperation;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::SplTokenConfidentialOperation;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::SplTokenConfidentialProofKind;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::SplTokenConfidentialProofLocation;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::SplTokenConfidentialProofReference;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::SplTokenDecryptableBalance;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::SplTokenElGamalCiphertext;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::SplTokenElGamalPubkey;
/// Exposes the audited Confidential Transfer operation inventory.
pub use crate::confidential::validate_confidential_proof_references;
/// Exposes the typed SPL Token executor.
pub use crate::executor::SplToken2022Executor;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::AMOUNT_TO_UI_AMOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::APPLY_PENDING_CONFIDENTIAL_BALANCE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::APPLY_PENDING_CONFIDENTIAL_BURN_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::APPROVE_CHECKED_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::APPROVE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::APPROVE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::BATCH_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::BURN_CHECKED_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::BURN_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::CLOSE_ACCOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::CONFIDENTIAL_BURN_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::CONFIDENTIAL_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::DEPOSIT_CONFIDENTIAL_TOKENS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::DISABLE_CONFIDENTIAL_CREDITS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::DISABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::DISABLE_CPI_GUARD_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::ENABLE_CONFIDENTIAL_CREDITS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::ENABLE_CONFIDENTIAL_TRANSFER_FEE_HARVEST_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::ENABLE_CPI_GUARD_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::ENABLE_NON_CONFIDENTIAL_CREDITS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::ENABLE_REQUIRED_TRANSFER_MEMOS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::FREEZE_ACCOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::GET_ACCOUNT_DATA_SIZE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::HARVEST_CONFIDENTIAL_WITHHELD_TOKENS_TO_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::HARVEST_WITHHELD_TOKENS_TO_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_ACCOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_CONFIDENTIAL_MINT_BURN_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_CONFIDENTIAL_TRANSFER_FEE_CONFIG_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_CONFIDENTIAL_TRANSFER_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_DEFAULT_ACCOUNT_STATE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_GROUP_MEMBER_POINTER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_GROUP_POINTER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_IMMUTABLE_OWNER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_INTEREST_BEARING_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_METADATA_POINTER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_MULTISIG_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_NON_TRANSFERABLE_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_PAUSABLE_CONFIG_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_PERMANENT_DELEGATE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_PERMISSIONED_BURN_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_SCALED_UI_AMOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_TOKEN_GROUP_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_TOKEN_METADATA_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_TRANSFER_FEE_CONFIG_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::INITIALIZE_TRANSFER_HOOK_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::MINT_TO_CHECKED_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::MINT_TO_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::PAUSE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::PERMISSIONED_BURN_CHECKED_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::PERMISSIONED_BURN_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::PERMISSIONED_CONFIDENTIAL_BURN_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::REALLOCATE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::REMOVE_TOKEN_METADATA_KEY_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::RESUME_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::REVOKE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::ROTATE_CONFIDENTIAL_SUPPLY_ELGAMAL_PUBKEY_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::SET_AUTHORITY_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::SET_TRANSFER_FEE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::SUPPORTED_OPERATION_CODES;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::SYNC_NATIVE_OPERATION;
/// Exposes the complete typed execution intent.
pub use crate::intent::SplToken2022ExecutionIntent;
/// Exposes the top-level operation contract.
pub use crate::intent::SplToken2022Operation;
/// Exposes the exact raw amount string contract.
pub use crate::intent::SplTokenAmount;
/// Exposes the typed authority contract.
pub use crate::intent::SplTokenAuthority;
/// Exposes the typed authority-kind contract.
pub use crate::intent::SplTokenAuthorityType;
/// Exposes the typed default-account-state contract.
pub use crate::intent::SplTokenDefaultAccountState;
/// Exposes the typed token-metadata field contract.
pub use crate::intent::SplTokenMetadataField;
/// Exposes the bounded scaled-UI multiplier contract.
pub use crate::intent::SplTokenMultiplier;
/// Exposes the non-batch operation contract.
pub use crate::intent::SplTokenSingleOperation;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::THAW_ACCOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::TRANSFER_CHECKED_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::TRANSFER_CHECKED_WITH_FEE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::TRANSFER_CONFIDENTIAL_TOKENS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::TRANSFER_CONFIDENTIAL_TOKENS_WITH_FEE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::TRANSFER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UI_AMOUNT_TO_AMOUNT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UNWRAP_LAMPORTS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_CONFIDENTIAL_DECRYPTABLE_SUPPLY_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_CONFIDENTIAL_TRANSFER_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_DEFAULT_ACCOUNT_STATE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_GROUP_MEMBER_POINTER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_GROUP_POINTER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_INTEREST_BEARING_RATE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_METADATA_POINTER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_TOKEN_METADATA_FIELD_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::UPDATE_TRANSFER_HOOK_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::WITHDRAW_CONFIDENTIAL_TOKENS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::WITHDRAW_CONFIDENTIAL_WITHHELD_TOKENS_FROM_MINT_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::WITHDRAW_EXCESS_LAMPORTS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::WITHDRAW_WITHHELD_TOKENS_FROM_ACCOUNTS_OPERATION;
/// Exposes stable operation codes for generic executor dispatch.
pub use crate::intent::WITHDRAW_WITHHELD_TOKENS_FROM_MINT_OPERATION;