spl: Bump token-2022 and friends (#33453)
* token: Update to 4.0.0 * token-2022: Bump and support new account and instruction types * Update token-2022 in fetch_spl / program-test * Fixup downstream uses * Mint and destination were flipped in 0.9.0 * Don't use `convert_pubkey` * Bump spl dependencies to versions which avoid recompilations
This commit is contained in:
parent
0e9e91c65e
commit
de38b05ad1
|
@ -709,7 +709,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b"
|
||||
dependencies = [
|
||||
"borsh-derive 0.10.3",
|
||||
"hashbrown 0.13.2",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3299,6 +3299,17 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
|
@ -3370,6 +3381,15 @@ dependencies = [
|
|||
"num_enum_derive 0.6.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb"
|
||||
dependencies = [
|
||||
"num_enum_derive 0.7.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.5.11"
|
||||
|
@ -3394,6 +3414,18 @@ dependencies = [
|
|||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597"
|
||||
dependencies = [
|
||||
"proc-macro-crate 1.1.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.3"
|
||||
|
@ -5077,8 +5109,10 @@ dependencies = [
|
|||
"serde_json",
|
||||
"solana-config-program",
|
||||
"solana-sdk",
|
||||
"spl-pod",
|
||||
"spl-token",
|
||||
"spl-token-2022",
|
||||
"spl-token-metadata-interface",
|
||||
"thiserror",
|
||||
"zstd",
|
||||
]
|
||||
|
@ -5155,7 +5189,7 @@ dependencies = [
|
|||
"memmap2",
|
||||
"memoffset 0.9.0",
|
||||
"modular-bitfield",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"num_cpus",
|
||||
"num_enum 0.6.1",
|
||||
|
@ -5198,7 +5232,7 @@ dependencies = [
|
|||
"bincode",
|
||||
"bytemuck",
|
||||
"log",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"rustc_version 0.4.0",
|
||||
"serde",
|
||||
|
@ -6160,6 +6194,7 @@ dependencies = [
|
|||
"solana-transaction-status",
|
||||
"solana-vote",
|
||||
"solana-vote-program",
|
||||
"spl-pod",
|
||||
"spl-token",
|
||||
"spl-token-2022",
|
||||
"static_assertions",
|
||||
|
@ -6483,7 +6518,7 @@ dependencies = [
|
|||
"log",
|
||||
"memoffset 0.9.0",
|
||||
"num-bigint 0.4.4",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"parking_lot 0.12.1",
|
||||
"rand 0.8.5",
|
||||
|
@ -6519,7 +6554,7 @@ dependencies = [
|
|||
"libc",
|
||||
"libsecp256k1",
|
||||
"log",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"percentage",
|
||||
"rand 0.8.5",
|
||||
|
@ -6632,7 +6667,7 @@ dependencies = [
|
|||
"dialoguer",
|
||||
"hidapi",
|
||||
"log",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"parking_lot 0.12.1",
|
||||
"qstring",
|
||||
|
@ -6691,6 +6726,7 @@ dependencies = [
|
|||
"solana-version",
|
||||
"solana-vote",
|
||||
"solana-vote-program",
|
||||
"spl-pod",
|
||||
"spl-token",
|
||||
"spl-token-2022",
|
||||
"stream-cancel",
|
||||
|
@ -6824,7 +6860,7 @@ dependencies = [
|
|||
"memmap2",
|
||||
"memoffset 0.9.0",
|
||||
"modular-bitfield",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"num_cpus",
|
||||
"num_enum 0.6.1",
|
||||
|
@ -6904,7 +6940,7 @@ dependencies = [
|
|||
"libsecp256k1",
|
||||
"log",
|
||||
"memmap2",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"num_enum 0.6.1",
|
||||
"pbkdf2 0.11.0",
|
||||
|
@ -7232,7 +7268,7 @@ dependencies = [
|
|||
"Inflector",
|
||||
"base64 0.21.4",
|
||||
"bincode",
|
||||
"borsh 0.9.3",
|
||||
"borsh 0.10.3",
|
||||
"bs58",
|
||||
"lazy_static",
|
||||
"log",
|
||||
|
@ -7410,7 +7446,7 @@ dependencies = [
|
|||
"assert_matches",
|
||||
"bincode",
|
||||
"log",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"rustc_version 0.4.0",
|
||||
"serde",
|
||||
|
@ -7471,7 +7507,7 @@ dependencies = [
|
|||
"bytemuck",
|
||||
"criterion",
|
||||
"curve25519-dalek",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
|
@ -7504,7 +7540,7 @@ dependencies = [
|
|||
"itertools",
|
||||
"lazy_static",
|
||||
"merlin",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
|
@ -7562,13 +7598,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "spl-associated-token-account"
|
||||
version = "1.1.3"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4"
|
||||
checksum = "385e31c29981488f2820b2022d8e731aae3b02e6e18e2fd854e4c9a94dc44fc3"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"borsh 0.9.3",
|
||||
"num-derive",
|
||||
"borsh 0.10.3",
|
||||
"num-derive 0.4.0",
|
||||
"num-traits",
|
||||
"solana-program",
|
||||
"spl-token",
|
||||
|
@ -7576,6 +7612,41 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-discriminator"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"spl-discriminator-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-discriminator-derive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fadbefec4f3c678215ca72bd71862697bb06b41fd77c0088902dd3203354387b"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"spl-discriminator-syn",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-discriminator-syn"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e5f2044ca42c8938d54d1255ce599c79a1ffd86b677dfab695caa20f9ffc3f2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sha2 0.10.7",
|
||||
"syn 2.0.37",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-instruction-padding"
|
||||
version = "0.1.0"
|
||||
|
@ -7588,46 +7659,145 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "spl-memo"
|
||||
version = "3.0.1"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325"
|
||||
checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a"
|
||||
dependencies = [
|
||||
"solana-program",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-token"
|
||||
version = "3.5.0"
|
||||
name = "spl-pod"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d"
|
||||
checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079"
|
||||
dependencies = [
|
||||
"borsh 0.10.3",
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"solana-zk-token-sdk",
|
||||
"spl-program-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-program-error"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c"
|
||||
dependencies = [
|
||||
"num-derive 0.4.0",
|
||||
"num-traits",
|
||||
"solana-program",
|
||||
"spl-program-error-derive",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-program-error-derive"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5269c8e868da17b6552ef35a51355a017bd8e0eae269c201fef830d35fa52c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sha2 0.10.7",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-tlv-account-resolution"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"spl-discriminator",
|
||||
"spl-pod",
|
||||
"spl-program-error",
|
||||
"spl-type-length-value",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-token"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
"num-derive",
|
||||
"num-derive 0.3.3",
|
||||
"num-traits",
|
||||
"num_enum 0.5.11",
|
||||
"num_enum 0.6.1",
|
||||
"solana-program",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-token-2022"
|
||||
version = "0.6.1"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47"
|
||||
checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
"num-derive",
|
||||
"num-derive 0.4.0",
|
||||
"num-traits",
|
||||
"num_enum 0.5.11",
|
||||
"num_enum 0.7.0",
|
||||
"solana-program",
|
||||
"solana-zk-token-sdk",
|
||||
"spl-memo",
|
||||
"spl-pod",
|
||||
"spl-token",
|
||||
"spl-token-metadata-interface",
|
||||
"spl-transfer-hook-interface",
|
||||
"spl-type-length-value",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-token-metadata-interface"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f"
|
||||
dependencies = [
|
||||
"borsh 0.10.3",
|
||||
"solana-program",
|
||||
"spl-discriminator",
|
||||
"spl-pod",
|
||||
"spl-program-error",
|
||||
"spl-type-length-value",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-transfer-hook-interface"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"spl-discriminator",
|
||||
"spl-pod",
|
||||
"spl-program-error",
|
||||
"spl-tlv-account-resolution",
|
||||
"spl-type-length-value",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-type-length-value"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"spl-discriminator",
|
||||
"spl-pod",
|
||||
"spl-program-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -373,11 +373,13 @@ solana-vote-program = { path = "programs/vote", version = "=1.17.0" }
|
|||
solana-zk-keygen = { path = "zk-keygen", version = "=1.17.0" }
|
||||
solana-zk-token-proof-program = { path = "programs/zk-token-proof", version = "=1.17.0" }
|
||||
solana-zk-token-sdk = { path = "zk-token-sdk", version = "=1.17.0" }
|
||||
spl-associated-token-account = "=1.1.3"
|
||||
spl-associated-token-account = "=2.2.0"
|
||||
spl-instruction-padding = "0.1"
|
||||
spl-memo = "=3.0.1"
|
||||
spl-token = "=3.5.0"
|
||||
spl-token-2022 = "=0.6.1"
|
||||
spl-memo = "=4.0.0"
|
||||
spl-pod = "=0.1.0"
|
||||
spl-token = "=4.0.0"
|
||||
spl-token-2022 = "=0.9.0"
|
||||
spl-token-metadata-interface = "=0.2.0"
|
||||
static_assertions = "1.1.0"
|
||||
stream-cancel = "0.8.1"
|
||||
strum = "0.24"
|
||||
|
@ -423,8 +425,10 @@ crossbeam-epoch = { git = "https://github.com/solana-labs/crossbeam", rev = "fd2
|
|||
# * spl-associated-token-account
|
||||
# * spl-instruction-padding
|
||||
# * spl-memo
|
||||
# * spl-pod
|
||||
# * spl-token
|
||||
# * spl-token-2022
|
||||
# * spl-token-metadata-interface
|
||||
#
|
||||
# They, in turn, depend on a number of crates that we also include directly using `path`
|
||||
# specifications. For example, `spl-token` depends on `solana-program`. And we explicitly specify
|
||||
|
|
|
@ -23,11 +23,13 @@ solana-config-program = { workspace = true }
|
|||
solana-sdk = { workspace = true }
|
||||
spl-token = { workspace = true, features = ["no-entrypoint"] }
|
||||
spl-token-2022 = { workspace = true, features = ["no-entrypoint"] }
|
||||
spl-token-metadata-interface = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
zstd = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = { workspace = true }
|
||||
spl-pod = { workspace = true }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
|
|
@ -290,12 +290,10 @@ mod test {
|
|||
use {
|
||||
super::*,
|
||||
crate::parse_token_extension::{UiMemoTransfer, UiMintCloseAuthority},
|
||||
spl_token_2022::{
|
||||
extension::{
|
||||
immutable_owner::ImmutableOwner, memo_transfer::MemoTransfer,
|
||||
mint_close_authority::MintCloseAuthority, ExtensionType, StateWithExtensionsMut,
|
||||
},
|
||||
pod::OptionalNonZeroPubkey,
|
||||
spl_pod::optional_keys::OptionalNonZeroPubkey,
|
||||
spl_token_2022::extension::{
|
||||
immutable_owner::ImmutableOwner, memo_transfer::MemoTransfer,
|
||||
mint_close_authority::MintCloseAuthority, ExtensionType, StateWithExtensionsMut,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -506,10 +504,11 @@ mod test {
|
|||
delegate: COption::None,
|
||||
delegated_amount: 0,
|
||||
};
|
||||
let account_size = ExtensionType::get_account_len::<Account>(&[
|
||||
let account_size = ExtensionType::try_calculate_account_len::<Account>(&[
|
||||
ExtensionType::ImmutableOwner,
|
||||
ExtensionType::MemoTransfer,
|
||||
]);
|
||||
])
|
||||
.unwrap();
|
||||
let mut account_data = vec![0; account_size];
|
||||
let mut account_state =
|
||||
StateWithExtensionsMut::<Account>::unpack_uninitialized(&mut account_data).unwrap();
|
||||
|
@ -586,7 +585,8 @@ mod test {
|
|||
fn test_parse_token_mint_with_extensions() {
|
||||
let owner_pubkey = SplTokenPubkey::new_from_array([3; 32]);
|
||||
let mint_size =
|
||||
ExtensionType::get_account_len::<Mint>(&[ExtensionType::MintCloseAuthority]);
|
||||
ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::MintCloseAuthority])
|
||||
.unwrap();
|
||||
let mint_base = Mint {
|
||||
mint_authority: COption::Some(owner_pubkey),
|
||||
supply: 42,
|
||||
|
|
|
@ -6,6 +6,7 @@ use {
|
|||
solana_program::pubkey::Pubkey,
|
||||
solana_zk_token_sdk::zk_token_elgamal::pod::ElGamalPubkey,
|
||||
},
|
||||
spl_token_metadata_interface::state::TokenMetadata,
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
|
@ -24,15 +25,21 @@ pub enum UiExtension {
|
|||
InterestBearingConfig(UiInterestBearingConfig),
|
||||
CpiGuard(UiCpiGuard),
|
||||
PermanentDelegate(UiPermanentDelegate),
|
||||
UnparseableExtension,
|
||||
NonTransferableAccount,
|
||||
ConfidentialTransferFeeConfig(UiConfidentialTransferFeeConfig),
|
||||
ConfidentialTransferFeeAmount(UiConfidentialTransferFeeAmount),
|
||||
TransferHook(UiTransferHook),
|
||||
TransferHookAccount(UiTransferHookAccount),
|
||||
MetadataPointer(UiMetadataPointer),
|
||||
TokenMetadata(UiTokenMetadata),
|
||||
UnparseableExtension,
|
||||
}
|
||||
|
||||
pub fn parse_extension<S: BaseState>(
|
||||
extension_type: &ExtensionType,
|
||||
account: &StateWithExtensions<S>,
|
||||
) -> UiExtension {
|
||||
match &extension_type {
|
||||
match extension_type {
|
||||
ExtensionType::Uninitialized => UiExtension::Uninitialized,
|
||||
ExtensionType::TransferFeeConfig => account
|
||||
.get_extension::<extension::transfer_fee::TransferFeeConfig>()
|
||||
|
@ -50,10 +57,18 @@ pub fn parse_extension<S: BaseState>(
|
|||
.get_extension::<extension::confidential_transfer::ConfidentialTransferMint>()
|
||||
.map(|&extension| UiExtension::ConfidentialTransferMint(extension.into()))
|
||||
.unwrap_or(UiExtension::UnparseableExtension),
|
||||
ExtensionType::ConfidentialTransferFeeConfig => account
|
||||
.get_extension::<extension::confidential_transfer_fee::ConfidentialTransferFeeConfig>()
|
||||
.map(|&extension| UiExtension::ConfidentialTransferFeeConfig(extension.into()))
|
||||
.unwrap_or(UiExtension::UnparseableExtension),
|
||||
ExtensionType::ConfidentialTransferAccount => account
|
||||
.get_extension::<extension::confidential_transfer::ConfidentialTransferAccount>()
|
||||
.map(|&extension| UiExtension::ConfidentialTransferAccount(extension.into()))
|
||||
.unwrap_or(UiExtension::UnparseableExtension),
|
||||
ExtensionType::ConfidentialTransferFeeAmount => account
|
||||
.get_extension::<extension::confidential_transfer_fee::ConfidentialTransferFeeAmount>()
|
||||
.map(|&extension| UiExtension::ConfidentialTransferFeeAmount(extension.into()))
|
||||
.unwrap_or(UiExtension::UnparseableExtension),
|
||||
ExtensionType::DefaultAccountState => account
|
||||
.get_extension::<extension::default_account_state::DefaultAccountState>()
|
||||
.map(|&extension| UiExtension::DefaultAccountState(extension.into()))
|
||||
|
@ -77,6 +92,22 @@ pub fn parse_extension<S: BaseState>(
|
|||
.map(|&extension| UiExtension::PermanentDelegate(extension.into()))
|
||||
.unwrap_or(UiExtension::UnparseableExtension),
|
||||
ExtensionType::NonTransferableAccount => UiExtension::NonTransferableAccount,
|
||||
ExtensionType::MetadataPointer => account
|
||||
.get_extension::<extension::metadata_pointer::MetadataPointer>()
|
||||
.map(|&extension| UiExtension::MetadataPointer(extension.into()))
|
||||
.unwrap_or(UiExtension::UnparseableExtension),
|
||||
ExtensionType::TokenMetadata => account
|
||||
.get_variable_len_extension::<TokenMetadata>()
|
||||
.map(|extension| UiExtension::TokenMetadata(extension.into()))
|
||||
.unwrap_or(UiExtension::UnparseableExtension),
|
||||
ExtensionType::TransferHook => account
|
||||
.get_extension::<extension::transfer_hook::TransferHook>()
|
||||
.map(|&extension| UiExtension::TransferHook(extension.into()))
|
||||
.unwrap_or(UiExtension::UnparseableExtension),
|
||||
ExtensionType::TransferHookAccount => account
|
||||
.get_extension::<extension::transfer_hook::TransferHookAccount>()
|
||||
.map(|&extension| UiExtension::TransferHookAccount(extension.into()))
|
||||
.unwrap_or(UiExtension::UnparseableExtension),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,9 +282,7 @@ impl From<extension::permanent_delegate::PermanentDelegate> for UiPermanentDeleg
|
|||
pub struct UiConfidentialTransferMint {
|
||||
pub authority: Option<String>,
|
||||
pub auto_approve_new_accounts: bool,
|
||||
pub auditor_encryption_pubkey: Option<String>,
|
||||
pub withdraw_withheld_authority_encryption_pubkey: Option<String>,
|
||||
pub withheld_amount: String,
|
||||
pub auditor_elgamal_pubkey: Option<String>,
|
||||
}
|
||||
|
||||
impl From<extension::confidential_transfer::ConfidentialTransferMint>
|
||||
|
@ -263,19 +292,44 @@ impl From<extension::confidential_transfer::ConfidentialTransferMint>
|
|||
confidential_transfer_mint: extension::confidential_transfer::ConfidentialTransferMint,
|
||||
) -> Self {
|
||||
let authority: Option<Pubkey> = confidential_transfer_mint.authority.into();
|
||||
let auditor_encryption_pubkey: Option<ElGamalPubkey> =
|
||||
confidential_transfer_mint.auditor_encryption_pubkey.into();
|
||||
let withdraw_withheld_authority_encryption_pubkey: Option<ElGamalPubkey> =
|
||||
confidential_transfer_mint
|
||||
.withdraw_withheld_authority_encryption_pubkey
|
||||
.into();
|
||||
let auditor_elgamal_pubkey: Option<ElGamalPubkey> =
|
||||
confidential_transfer_mint.auditor_elgamal_pubkey.into();
|
||||
Self {
|
||||
authority: authority.map(|pubkey| pubkey.to_string()),
|
||||
auto_approve_new_accounts: confidential_transfer_mint.auto_approve_new_accounts.into(),
|
||||
auditor_encryption_pubkey: auditor_encryption_pubkey.map(|pubkey| pubkey.to_string()),
|
||||
withdraw_withheld_authority_encryption_pubkey:
|
||||
withdraw_withheld_authority_encryption_pubkey.map(|pubkey| pubkey.to_string()),
|
||||
withheld_amount: format!("{}", confidential_transfer_mint.withheld_amount),
|
||||
auditor_elgamal_pubkey: auditor_elgamal_pubkey.map(|pubkey| pubkey.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UiConfidentialTransferFeeConfig {
|
||||
pub authority: Option<String>,
|
||||
pub withdraw_withheld_authority_elgamal_pubkey: Option<String>,
|
||||
pub harvest_to_mint_enabled: bool,
|
||||
pub withheld_amount: String,
|
||||
}
|
||||
|
||||
impl From<extension::confidential_transfer_fee::ConfidentialTransferFeeConfig>
|
||||
for UiConfidentialTransferFeeConfig
|
||||
{
|
||||
fn from(
|
||||
confidential_transfer_fee_config: extension::confidential_transfer_fee::ConfidentialTransferFeeConfig,
|
||||
) -> Self {
|
||||
let authority: Option<Pubkey> = confidential_transfer_fee_config.authority.into();
|
||||
let withdraw_withheld_authority_elgamal_pubkey: Option<ElGamalPubkey> =
|
||||
confidential_transfer_fee_config
|
||||
.withdraw_withheld_authority_elgamal_pubkey
|
||||
.into();
|
||||
Self {
|
||||
authority: authority.map(|pubkey| pubkey.to_string()),
|
||||
withdraw_withheld_authority_elgamal_pubkey: withdraw_withheld_authority_elgamal_pubkey
|
||||
.map(|pubkey| pubkey.to_string()),
|
||||
harvest_to_mint_enabled: confidential_transfer_fee_config
|
||||
.harvest_to_mint_enabled
|
||||
.into(),
|
||||
withheld_amount: format!("{}", confidential_transfer_fee_config.withheld_amount),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -284,7 +338,7 @@ impl From<extension::confidential_transfer::ConfidentialTransferMint>
|
|||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UiConfidentialTransferAccount {
|
||||
pub approved: bool,
|
||||
pub encryption_pubkey: String,
|
||||
pub elgamal_pubkey: String,
|
||||
pub pending_balance_lo: String,
|
||||
pub pending_balance_hi: String,
|
||||
pub available_balance: String,
|
||||
|
@ -295,7 +349,6 @@ pub struct UiConfidentialTransferAccount {
|
|||
pub maximum_pending_balance_credit_counter: u64,
|
||||
pub expected_pending_balance_credit_counter: u64,
|
||||
pub actual_pending_balance_credit_counter: u64,
|
||||
pub withheld_amount: String,
|
||||
}
|
||||
|
||||
impl From<extension::confidential_transfer::ConfidentialTransferAccount>
|
||||
|
@ -306,7 +359,7 @@ impl From<extension::confidential_transfer::ConfidentialTransferAccount>
|
|||
) -> Self {
|
||||
Self {
|
||||
approved: confidential_transfer_account.approved.into(),
|
||||
encryption_pubkey: format!("{}", confidential_transfer_account.encryption_pubkey),
|
||||
elgamal_pubkey: format!("{}", confidential_transfer_account.elgamal_pubkey),
|
||||
pending_balance_lo: format!("{}", confidential_transfer_account.pending_balance_lo),
|
||||
pending_balance_hi: format!("{}", confidential_transfer_account.pending_balance_hi),
|
||||
available_balance: format!("{}", confidential_transfer_account.available_balance),
|
||||
|
@ -332,7 +385,99 @@ impl From<extension::confidential_transfer::ConfidentialTransferAccount>
|
|||
actual_pending_balance_credit_counter: confidential_transfer_account
|
||||
.actual_pending_balance_credit_counter
|
||||
.into(),
|
||||
withheld_amount: format!("{}", confidential_transfer_account.withheld_amount),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UiConfidentialTransferFeeAmount {
|
||||
pub withheld_amount: String,
|
||||
}
|
||||
|
||||
impl From<extension::confidential_transfer_fee::ConfidentialTransferFeeAmount>
|
||||
for UiConfidentialTransferFeeAmount
|
||||
{
|
||||
fn from(
|
||||
confidential_transfer_fee_amount: extension::confidential_transfer_fee::ConfidentialTransferFeeAmount,
|
||||
) -> Self {
|
||||
Self {
|
||||
withheld_amount: format!("{}", confidential_transfer_fee_amount.withheld_amount),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UiMetadataPointer {
|
||||
pub authority: Option<String>,
|
||||
pub metadata_address: Option<String>,
|
||||
}
|
||||
|
||||
impl From<extension::metadata_pointer::MetadataPointer> for UiMetadataPointer {
|
||||
fn from(metadata_pointer: extension::metadata_pointer::MetadataPointer) -> Self {
|
||||
let authority: Option<Pubkey> = metadata_pointer.authority.into();
|
||||
let metadata_address: Option<Pubkey> = metadata_pointer.metadata_address.into();
|
||||
Self {
|
||||
authority: authority.map(|pubkey| pubkey.to_string()),
|
||||
metadata_address: metadata_address.map(|pubkey| pubkey.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UiTokenMetadata {
|
||||
pub update_authority: Option<String>,
|
||||
pub mint: String,
|
||||
pub name: String,
|
||||
pub symbol: String,
|
||||
pub uri: String,
|
||||
pub additional_metadata: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
impl From<TokenMetadata> for UiTokenMetadata {
|
||||
fn from(token_metadata: TokenMetadata) -> Self {
|
||||
let update_authority: Option<Pubkey> = token_metadata.update_authority.into();
|
||||
Self {
|
||||
update_authority: update_authority.map(|pubkey| pubkey.to_string()),
|
||||
mint: token_metadata.mint.to_string(),
|
||||
name: token_metadata.name,
|
||||
symbol: token_metadata.symbol,
|
||||
uri: token_metadata.uri,
|
||||
additional_metadata: token_metadata.additional_metadata,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UiTransferHook {
|
||||
pub authority: Option<String>,
|
||||
pub program_id: Option<String>,
|
||||
}
|
||||
|
||||
impl From<extension::transfer_hook::TransferHook> for UiTransferHook {
|
||||
fn from(transfer_hook: extension::transfer_hook::TransferHook) -> Self {
|
||||
let authority: Option<Pubkey> = transfer_hook.authority.into();
|
||||
let program_id: Option<Pubkey> = transfer_hook.program_id.into();
|
||||
Self {
|
||||
authority: authority.map(|pubkey| pubkey.to_string()),
|
||||
program_id: program_id.map(|pubkey| pubkey.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UiTransferHookAccount {
|
||||
pub transferring: bool,
|
||||
}
|
||||
|
||||
impl From<extension::transfer_hook::TransferHookAccount> for UiTransferHookAccount {
|
||||
fn from(transfer_hook: extension::transfer_hook::TransferHookAccount) -> Self {
|
||||
Self {
|
||||
transferring: transfer_hook.transferring.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ fetch_program() {
|
|||
}
|
||||
|
||||
fetch_program token 3.5.0 TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA BPFLoader2111111111111111111111111111111111
|
||||
fetch_program token-2022 0.6.0 TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb BPFLoaderUpgradeab1e11111111111111111111111
|
||||
fetch_program token-2022 0.9.0 TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb BPFLoaderUpgradeab1e11111111111111111111111
|
||||
fetch_program memo 1.0.0 Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo BPFLoader1111111111111111111111111111111111
|
||||
fetch_program memo 3.0.0 MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr BPFLoader2111111111111111111111111111111111
|
||||
fetch_program associated-token-account 1.1.2 ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL BPFLoader2111111111111111111111111111111111
|
||||
|
|
|
@ -78,6 +78,7 @@ features = ["lz4"]
|
|||
bs58 = { workspace = true }
|
||||
solana-account-decoder = { workspace = true }
|
||||
solana-logger = { workspace = true }
|
||||
spl-pod = { workspace = true }
|
||||
test-case = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
@ -121,12 +121,12 @@ mod test {
|
|||
use {
|
||||
super::*,
|
||||
solana_sdk::{account::Account, genesis_config::create_genesis_config},
|
||||
spl_pod::optional_keys::OptionalNonZeroPubkey,
|
||||
spl_token_2022::{
|
||||
extension::{
|
||||
immutable_owner::ImmutableOwner, memo_transfer::MemoTransfer,
|
||||
mint_close_authority::MintCloseAuthority, ExtensionType, StateWithExtensionsMut,
|
||||
},
|
||||
pod::OptionalNonZeroPubkey,
|
||||
solana_program::{program_option::COption, program_pack::Pack},
|
||||
},
|
||||
std::collections::BTreeMap,
|
||||
|
@ -291,7 +291,8 @@ mod test {
|
|||
|
||||
let mint_authority = Pubkey::new_unique();
|
||||
let mint_size =
|
||||
ExtensionType::get_account_len::<Mint>(&[ExtensionType::MintCloseAuthority]);
|
||||
ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::MintCloseAuthority])
|
||||
.unwrap();
|
||||
let mint_base = Mint {
|
||||
mint_authority: COption::None,
|
||||
supply: 4242,
|
||||
|
@ -339,10 +340,11 @@ mod test {
|
|||
delegated_amount: 0,
|
||||
close_authority: COption::None,
|
||||
};
|
||||
let account_size = ExtensionType::get_account_len::<TokenAccount>(&[
|
||||
let account_size = ExtensionType::try_calculate_account_len::<TokenAccount>(&[
|
||||
ExtensionType::ImmutableOwner,
|
||||
ExtensionType::MemoTransfer,
|
||||
]);
|
||||
])
|
||||
.unwrap();
|
||||
let mut account_data = vec![0; account_size];
|
||||
let mut account_state =
|
||||
StateWithExtensionsMut::<TokenAccount>::unpack_uninitialized(&mut account_data)
|
||||
|
@ -381,10 +383,11 @@ mod test {
|
|||
delegated_amount: 0,
|
||||
close_authority: COption::None,
|
||||
};
|
||||
let account_size = ExtensionType::get_account_len::<TokenAccount>(&[
|
||||
let account_size = ExtensionType::try_calculate_account_len::<TokenAccount>(&[
|
||||
ExtensionType::ImmutableOwner,
|
||||
ExtensionType::MemoTransfer,
|
||||
]);
|
||||
])
|
||||
.unwrap();
|
||||
let mut account_data = vec![0; account_size];
|
||||
let mut account_state =
|
||||
StateWithExtensionsMut::<TokenAccount>::unpack_uninitialized(&mut account_data)
|
||||
|
|
|
@ -30,7 +30,7 @@ static SPL_PROGRAMS: &[(Pubkey, Pubkey, &[u8])] = &[
|
|||
(
|
||||
spl_token_2022::ID,
|
||||
solana_sdk::bpf_loader_upgradeable::ID,
|
||||
include_bytes!("programs/spl_token_2022-0.6.0.so"),
|
||||
include_bytes!("programs/spl_token_2022-0.9.0.so"),
|
||||
),
|
||||
(
|
||||
spl_memo_1_0::ID,
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -2918,6 +2918,17 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.42"
|
||||
|
@ -2970,15 +2981,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d829733185c1ca374f17e52b762f24f535ec625d2cc1f070e34c8a9068f341b"
|
||||
dependencies = [
|
||||
"num_enum_derive 0.5.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.6.1"
|
||||
|
@ -2989,15 +2991,12 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.5.9"
|
||||
name = "num_enum"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2be1598bf1c313dcdd12092e3f1920f463462525a21b7b4e11b4168353d0123e"
|
||||
checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb"
|
||||
dependencies = [
|
||||
"proc-macro-crate 1.1.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"num_enum_derive 0.7.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3012,6 +3011,18 @@ dependencies = [
|
|||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597"
|
||||
dependencies = [
|
||||
"proc-macro-crate 1.1.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.5"
|
||||
|
@ -4450,6 +4461,7 @@ dependencies = [
|
|||
"solana-sdk",
|
||||
"spl-token",
|
||||
"spl-token-2022",
|
||||
"spl-token-metadata-interface",
|
||||
"thiserror",
|
||||
"zstd",
|
||||
]
|
||||
|
@ -4478,7 +4490,7 @@ dependencies = [
|
|||
"lz4",
|
||||
"memmap2",
|
||||
"modular-bitfield",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"num_cpus",
|
||||
"num_enum 0.6.1",
|
||||
|
@ -4518,7 +4530,7 @@ dependencies = [
|
|||
"bincode",
|
||||
"bytemuck",
|
||||
"log",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
|
@ -5241,7 +5253,7 @@ dependencies = [
|
|||
"log",
|
||||
"memoffset 0.9.0",
|
||||
"num-bigint 0.4.4",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"parking_lot 0.12.1",
|
||||
"rand 0.8.5",
|
||||
|
@ -5273,7 +5285,7 @@ dependencies = [
|
|||
"itertools",
|
||||
"libc",
|
||||
"log",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"percentage",
|
||||
"rand 0.8.5",
|
||||
|
@ -5378,7 +5390,7 @@ dependencies = [
|
|||
"console",
|
||||
"dialoguer",
|
||||
"log",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"parking_lot 0.12.1",
|
||||
"qstring",
|
||||
|
@ -5525,7 +5537,7 @@ dependencies = [
|
|||
"lz4",
|
||||
"memmap2",
|
||||
"modular-bitfield",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"num_cpus",
|
||||
"num_enum 0.6.1",
|
||||
|
@ -5695,7 +5707,7 @@ dependencies = [
|
|||
name = "solana-sbf-rust-error-handling"
|
||||
version = "1.17.0"
|
||||
dependencies = [
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"solana-program",
|
||||
"thiserror",
|
||||
|
@ -6020,7 +6032,7 @@ dependencies = [
|
|||
"libsecp256k1 0.6.0",
|
||||
"log",
|
||||
"memmap2",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"num_enum 0.6.1",
|
||||
"pbkdf2 0.11.0",
|
||||
|
@ -6246,7 +6258,7 @@ dependencies = [
|
|||
"Inflector",
|
||||
"base64 0.21.4",
|
||||
"bincode",
|
||||
"borsh 0.9.3",
|
||||
"borsh 0.10.3",
|
||||
"bs58",
|
||||
"lazy_static",
|
||||
"log",
|
||||
|
@ -6409,7 +6421,7 @@ version = "1.17.0"
|
|||
dependencies = [
|
||||
"bincode",
|
||||
"log",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
|
@ -6428,7 +6440,7 @@ name = "solana-zk-token-proof-program"
|
|||
version = "1.17.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
|
@ -6449,7 +6461,7 @@ dependencies = [
|
|||
"itertools",
|
||||
"lazy_static",
|
||||
"merlin",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
|
@ -6505,13 +6517,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "spl-associated-token-account"
|
||||
version = "1.1.3"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4"
|
||||
checksum = "385e31c29981488f2820b2022d8e731aae3b02e6e18e2fd854e4c9a94dc44fc3"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"borsh 0.9.3",
|
||||
"num-derive",
|
||||
"borsh 0.10.3",
|
||||
"num-derive 0.4.0",
|
||||
"num-traits",
|
||||
"solana-program",
|
||||
"spl-token",
|
||||
|
@ -6520,47 +6532,181 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-memo"
|
||||
version = "3.0.1"
|
||||
name = "spl-discriminator"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325"
|
||||
checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"spl-discriminator-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-discriminator-derive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fadbefec4f3c678215ca72bd71862697bb06b41fd77c0088902dd3203354387b"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"spl-discriminator-syn",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-discriminator-syn"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e5f2044ca42c8938d54d1255ce599c79a1ffd86b677dfab695caa20f9ffc3f2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sha2 0.10.7",
|
||||
"syn 2.0.37",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-memo"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a"
|
||||
dependencies = [
|
||||
"solana-program",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-token"
|
||||
version = "3.5.0"
|
||||
name = "spl-pod"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d"
|
||||
checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079"
|
||||
dependencies = [
|
||||
"borsh 0.10.3",
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"solana-zk-token-sdk",
|
||||
"spl-program-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-program-error"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c"
|
||||
dependencies = [
|
||||
"num-derive 0.4.0",
|
||||
"num-traits",
|
||||
"solana-program",
|
||||
"spl-program-error-derive",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-program-error-derive"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5269c8e868da17b6552ef35a51355a017bd8e0eae269c201fef830d35fa52c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sha2 0.10.7",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-tlv-account-resolution"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"spl-discriminator",
|
||||
"spl-pod",
|
||||
"spl-program-error",
|
||||
"spl-type-length-value",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-token"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
"num-derive",
|
||||
"num-derive 0.3.0",
|
||||
"num-traits",
|
||||
"num_enum 0.5.9",
|
||||
"num_enum 0.6.1",
|
||||
"solana-program",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-token-2022"
|
||||
version = "0.6.1"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47"
|
||||
checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
"num-derive",
|
||||
"num-derive 0.4.0",
|
||||
"num-traits",
|
||||
"num_enum 0.5.9",
|
||||
"num_enum 0.7.0",
|
||||
"solana-program",
|
||||
"solana-zk-token-sdk",
|
||||
"spl-memo",
|
||||
"spl-pod",
|
||||
"spl-token",
|
||||
"spl-token-metadata-interface",
|
||||
"spl-transfer-hook-interface",
|
||||
"spl-type-length-value",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-token-metadata-interface"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f"
|
||||
dependencies = [
|
||||
"borsh 0.10.3",
|
||||
"solana-program",
|
||||
"spl-discriminator",
|
||||
"spl-pod",
|
||||
"spl-program-error",
|
||||
"spl-type-length-value",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-transfer-hook-interface"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"spl-discriminator",
|
||||
"spl-pod",
|
||||
"spl-program-error",
|
||||
"spl-tlv-account-resolution",
|
||||
"spl-type-length-value",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spl-type-length-value"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"solana-program",
|
||||
"spl-discriminator",
|
||||
"spl-pod",
|
||||
"spl-program-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
|
|
|
@ -171,8 +171,10 @@ targets = ["x86_64-unknown-linux-gnu"]
|
|||
# * spl-associated-token-account
|
||||
# * spl-instruction-padding
|
||||
# * spl-memo
|
||||
# * spl-pod
|
||||
# * spl-token
|
||||
# * spl-token-2022
|
||||
# * spl-token-metadata-interface
|
||||
#
|
||||
# They are included indirectly, for example, `account-decoder` depends on
|
||||
#
|
||||
|
|
|
@ -64,6 +64,7 @@ tokio-util = { workspace = true, features = ["codec", "compat"] }
|
|||
serial_test = { workspace = true }
|
||||
solana-net-utils = { workspace = true }
|
||||
solana-stake-program = { workspace = true }
|
||||
spl-pod = { workspace = true }
|
||||
symlink = { workspace = true }
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -4683,12 +4683,12 @@ pub mod tests {
|
|||
vote_instruction,
|
||||
vote_state::{self, Vote, VoteInit, VoteStateVersions, MAX_LOCKOUT_HISTORY},
|
||||
},
|
||||
spl_pod::optional_keys::OptionalNonZeroPubkey,
|
||||
spl_token_2022::{
|
||||
extension::{
|
||||
immutable_owner::ImmutableOwner, memo_transfer::MemoTransfer,
|
||||
mint_close_authority::MintCloseAuthority, ExtensionType, StateWithExtensionsMut,
|
||||
},
|
||||
pod::OptionalNonZeroPubkey,
|
||||
solana_program::{program_option::COption, pubkey::Pubkey as SplTokenPubkey},
|
||||
state::{AccountState as TokenAccountState, Mint},
|
||||
},
|
||||
|
@ -7439,10 +7439,11 @@ pub mod tests {
|
|||
delegated_amount: 30,
|
||||
close_authority: COption::Some(owner),
|
||||
};
|
||||
let account_size = ExtensionType::get_account_len::<TokenAccount>(&[
|
||||
let account_size = ExtensionType::try_calculate_account_len::<TokenAccount>(&[
|
||||
ExtensionType::ImmutableOwner,
|
||||
ExtensionType::MemoTransfer,
|
||||
]);
|
||||
])
|
||||
.unwrap();
|
||||
let mut account_data = vec![0; account_size];
|
||||
let mut account_state =
|
||||
StateWithExtensionsMut::<TokenAccount>::unpack_uninitialized(&mut account_data)
|
||||
|
@ -7466,8 +7467,10 @@ pub mod tests {
|
|||
bank.store_account(&token_account_pubkey, &token_account);
|
||||
|
||||
// Add the mint
|
||||
let mint_size =
|
||||
ExtensionType::get_account_len::<Mint>(&[ExtensionType::MintCloseAuthority]);
|
||||
let mint_size = ExtensionType::try_calculate_account_len::<Mint>(&[
|
||||
ExtensionType::MintCloseAuthority,
|
||||
])
|
||||
.unwrap();
|
||||
let mint_base = Mint {
|
||||
mint_authority: COption::Some(owner),
|
||||
supply: 500,
|
||||
|
@ -7931,10 +7934,11 @@ pub mod tests {
|
|||
delegated_amount: 30,
|
||||
close_authority: COption::Some(owner),
|
||||
};
|
||||
let account_size = ExtensionType::get_account_len::<TokenAccount>(&[
|
||||
let account_size = ExtensionType::try_calculate_account_len::<TokenAccount>(&[
|
||||
ExtensionType::ImmutableOwner,
|
||||
ExtensionType::MemoTransfer,
|
||||
]);
|
||||
])
|
||||
.unwrap();
|
||||
let mut account_data = vec![0; account_size];
|
||||
let mut account_state =
|
||||
StateWithExtensionsMut::<TokenAccount>::unpack_uninitialized(&mut account_data)
|
||||
|
@ -7957,8 +7961,10 @@ pub mod tests {
|
|||
});
|
||||
bank.store_account(&token_account_pubkey, &token_account);
|
||||
|
||||
let mint_size =
|
||||
ExtensionType::get_account_len::<Mint>(&[ExtensionType::MintCloseAuthority]);
|
||||
let mint_size = ExtensionType::try_calculate_account_len::<Mint>(&[
|
||||
ExtensionType::MintCloseAuthority,
|
||||
])
|
||||
.unwrap();
|
||||
let mint_base = Mint {
|
||||
mint_authority: COption::Some(owner),
|
||||
supply: 500,
|
||||
|
|
|
@ -13,8 +13,7 @@ edition = { workspace = true }
|
|||
Inflector = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
bincode = { workspace = true }
|
||||
# NOTE: Use the workspace version once spl-associated-token-account uses borsh 0.10.
|
||||
borsh0-9 = { package = "borsh", version = "0.9.3" }
|
||||
borsh = { workspace = true }
|
||||
bs58 = { workspace = true }
|
||||
lazy_static = { workspace = true }
|
||||
log = { workspace = true }
|
||||
|
|
|
@ -2,7 +2,7 @@ use {
|
|||
crate::parse_instruction::{
|
||||
check_num_accounts, ParsableProgram, ParseInstructionError, ParsedInstructionEnum,
|
||||
},
|
||||
borsh0_9::BorshDeserialize,
|
||||
borsh::BorshDeserialize,
|
||||
serde_json::json,
|
||||
solana_sdk::{instruction::CompiledInstruction, message::AccountKeys, pubkey::Pubkey},
|
||||
spl_associated_token_account::instruction::AssociatedTokenAccountInstruction,
|
||||
|
|
|
@ -3,9 +3,10 @@ use {
|
|||
check_num_accounts, ParsableProgram, ParseInstructionError, ParsedInstructionEnum,
|
||||
},
|
||||
extension::{
|
||||
confidential_transfer::*, cpi_guard::*, default_account_state::*, interest_bearing_mint::*,
|
||||
memo_transfer::*, mint_close_authority::*, permanent_delegate::*, reallocate::*,
|
||||
transfer_fee::*,
|
||||
confidential_transfer::*, confidential_transfer_fee::*, cpi_guard::*,
|
||||
default_account_state::*, interest_bearing_mint::*, memo_transfer::*, metadata_pointer::*,
|
||||
mint_close_authority::*, permanent_delegate::*, reallocate::*, transfer_fee::*,
|
||||
transfer_hook::*,
|
||||
},
|
||||
serde_json::{json, Map, Value},
|
||||
solana_account_decoder::parse_token::{token_amount_to_ui_amount, UiAccountState},
|
||||
|
@ -229,7 +230,10 @@ pub fn parse_token(
|
|||
| AuthorityType::CloseMint
|
||||
| AuthorityType::InterestRate
|
||||
| AuthorityType::PermanentDelegate
|
||||
| AuthorityType::ConfidentialTransferMint => "mint",
|
||||
| AuthorityType::ConfidentialTransferMint
|
||||
| AuthorityType::TransferHookProgramId
|
||||
| AuthorityType::ConfidentialTransferFeeConfig
|
||||
| AuthorityType::MetadataPointer => "mint",
|
||||
AuthorityType::AccountOwner | AuthorityType::CloseAccount => "account",
|
||||
};
|
||||
let mut value = json!({
|
||||
|
@ -590,6 +594,62 @@ pub fn parse_token(
|
|||
account_keys,
|
||||
)
|
||||
}
|
||||
TokenInstruction::TransferHookExtension => {
|
||||
if instruction.data.len() < 2 {
|
||||
return Err(ParseInstructionError::InstructionNotParsable(
|
||||
ParsableProgram::SplToken,
|
||||
));
|
||||
}
|
||||
parse_transfer_hook_instruction(
|
||||
&instruction.data[1..],
|
||||
&instruction.accounts,
|
||||
account_keys,
|
||||
)
|
||||
}
|
||||
TokenInstruction::ConfidentialTransferFeeExtension => {
|
||||
if instruction.data.len() < 2 {
|
||||
return Err(ParseInstructionError::InstructionNotParsable(
|
||||
ParsableProgram::SplToken,
|
||||
));
|
||||
}
|
||||
parse_confidential_transfer_fee_instruction(
|
||||
&instruction.data[1..],
|
||||
&instruction.accounts,
|
||||
account_keys,
|
||||
)
|
||||
}
|
||||
TokenInstruction::WithdrawExcessLamports => {
|
||||
check_num_token_accounts(&instruction.accounts, 3)?;
|
||||
let mut value = json!({
|
||||
"source": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"destination": account_keys[instruction.accounts[1] as usize].to_string(),
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
parse_signers(
|
||||
map,
|
||||
2,
|
||||
account_keys,
|
||||
&instruction.accounts,
|
||||
"authority",
|
||||
"multisigAuthority",
|
||||
);
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "withdrawExcessLamports".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
TokenInstruction::MetadataPointerExtension => {
|
||||
if instruction.data.len() < 2 {
|
||||
return Err(ParseInstructionError::InstructionNotParsable(
|
||||
ParsableProgram::SplToken,
|
||||
));
|
||||
}
|
||||
parse_metadata_pointer_instruction(
|
||||
&instruction.data[1..],
|
||||
&instruction.accounts,
|
||||
account_keys,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -606,6 +666,9 @@ pub enum UiAuthorityType {
|
|||
InterestRate,
|
||||
PermanentDelegate,
|
||||
ConfidentialTransferMint,
|
||||
TransferHookProgramId,
|
||||
ConfidentialTransferFeeConfig,
|
||||
MetadataPointer,
|
||||
}
|
||||
|
||||
impl From<AuthorityType> for UiAuthorityType {
|
||||
|
@ -621,6 +684,11 @@ impl From<AuthorityType> for UiAuthorityType {
|
|||
AuthorityType::InterestRate => UiAuthorityType::InterestRate,
|
||||
AuthorityType::PermanentDelegate => UiAuthorityType::PermanentDelegate,
|
||||
AuthorityType::ConfidentialTransferMint => UiAuthorityType::ConfidentialTransferMint,
|
||||
AuthorityType::TransferHookProgramId => UiAuthorityType::TransferHookProgramId,
|
||||
AuthorityType::ConfidentialTransferFeeConfig => {
|
||||
UiAuthorityType::ConfidentialTransferFeeConfig
|
||||
}
|
||||
AuthorityType::MetadataPointer => UiAuthorityType::MetadataPointer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -642,6 +710,12 @@ pub enum UiExtensionType {
|
|||
CpiGuard,
|
||||
PermanentDelegate,
|
||||
NonTransferableAccount,
|
||||
TransferHook,
|
||||
TransferHookAccount,
|
||||
ConfidentialTransferFeeConfig,
|
||||
ConfidentialTransferFeeAmount,
|
||||
MetadataPointer,
|
||||
TokenMetadata,
|
||||
}
|
||||
|
||||
impl From<ExtensionType> for UiExtensionType {
|
||||
|
@ -663,6 +737,16 @@ impl From<ExtensionType> for UiExtensionType {
|
|||
ExtensionType::CpiGuard => UiExtensionType::CpiGuard,
|
||||
ExtensionType::PermanentDelegate => UiExtensionType::PermanentDelegate,
|
||||
ExtensionType::NonTransferableAccount => UiExtensionType::NonTransferableAccount,
|
||||
ExtensionType::TransferHook => UiExtensionType::TransferHook,
|
||||
ExtensionType::TransferHookAccount => UiExtensionType::TransferHookAccount,
|
||||
ExtensionType::ConfidentialTransferFeeConfig => {
|
||||
UiExtensionType::ConfidentialTransferFeeConfig
|
||||
}
|
||||
ExtensionType::ConfidentialTransferFeeAmount => {
|
||||
UiExtensionType::ConfidentialTransferFeeAmount
|
||||
}
|
||||
ExtensionType::MetadataPointer => UiExtensionType::MetadataPointer,
|
||||
ExtensionType::TokenMetadata => UiExtensionType::TokenMetadata,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,8 +192,8 @@ pub(in crate::parse_token) fn parse_confidential_transfer_instruction(
|
|||
let proof_instruction_offset: i8 = transfer_data.proof_instruction_offset;
|
||||
let mut value = json!({
|
||||
"source": account_keys[account_indexes[0] as usize].to_string(),
|
||||
"destination": account_keys[account_indexes[1] as usize].to_string(),
|
||||
"mint": account_keys[account_indexes[2] as usize].to_string(),
|
||||
"mint": account_keys[account_indexes[1] as usize].to_string(),
|
||||
"destination": account_keys[account_indexes[2] as usize].to_string(),
|
||||
"instructionsSysvar": account_keys[account_indexes[3] as usize].to_string(),
|
||||
"newSourceDecryptableAvailableBalance": format!("{}", transfer_data.new_source_decryptable_available_balance),
|
||||
"proofInstructionOffset": proof_instruction_offset,
|
||||
|
@ -322,85 +322,37 @@ pub(in crate::parse_token) fn parse_confidential_transfer_instruction(
|
|||
info: value,
|
||||
})
|
||||
}
|
||||
ConfidentialTransferInstruction::WithdrawWithheldTokensFromMint => {
|
||||
check_num_token_accounts(account_indexes, 4)?;
|
||||
let withdraw_withheld_data: WithdrawWithheldTokensFromMintData =
|
||||
ConfidentialTransferInstruction::TransferWithSplitProofs => {
|
||||
check_num_token_accounts(account_indexes, 7)?;
|
||||
let transfer_data: TransferWithSplitProofsInstructionData =
|
||||
*decode_instruction_data(instruction_data).map_err(|_| {
|
||||
ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
|
||||
})?;
|
||||
let proof_instruction_offset: i8 = withdraw_withheld_data.proof_instruction_offset;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
"feeRecipient": account_keys[account_indexes[1] as usize].to_string(),
|
||||
"instructionsSysvar": account_keys[account_indexes[2] as usize].to_string(),
|
||||
"proofInstructionOffset": proof_instruction_offset,
|
||||
|
||||
"source": account_keys[account_indexes[0] as usize].to_string(),
|
||||
"mint": account_keys[account_indexes[1] as usize].to_string(),
|
||||
"destination": account_keys[account_indexes[2] as usize].to_string(),
|
||||
"ciphertextCommitmentEqualityContext": account_keys[account_indexes[3] as usize].to_string(),
|
||||
"batchedGroupedCiphertext2HandlesValidityContext": account_keys[account_indexes[4] as usize].to_string(),
|
||||
"batchedRangeProofContext": account_keys[account_indexes[5] as usize].to_string(),
|
||||
"owner": account_keys[account_indexes[6] as usize].to_string(),
|
||||
"newSourceDecryptableAvailableBalance": format!("{}", transfer_data.new_source_decryptable_available_balance),
|
||||
"noOpOnUninitializedSplitContextState": bool::from(transfer_data.no_op_on_uninitialized_split_context_state),
|
||||
"closeSplitContextStateOnExecution": bool::from(transfer_data.close_split_context_state_on_execution),
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
parse_signers(
|
||||
map,
|
||||
3,
|
||||
account_keys,
|
||||
account_indexes,
|
||||
"withdrawWithheldAuthority",
|
||||
"multisigWithdrawWithheldAuthority",
|
||||
);
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "withdrawWithheldConfidentialTransferTokensFromMint".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
ConfidentialTransferInstruction::WithdrawWithheldTokensFromAccounts => {
|
||||
let withdraw_withheld_data: WithdrawWithheldTokensFromAccountsData =
|
||||
*decode_instruction_data(instruction_data).map_err(|_| {
|
||||
ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
|
||||
})?;
|
||||
let num_token_accounts = withdraw_withheld_data.num_token_accounts;
|
||||
check_num_token_accounts(account_indexes, 4 + num_token_accounts as usize)?;
|
||||
let proof_instruction_offset: i8 = withdraw_withheld_data.proof_instruction_offset;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
"feeRecipient": account_keys[account_indexes[1] as usize].to_string(),
|
||||
"instructionsSysvar": account_keys[account_indexes[2] as usize].to_string(),
|
||||
"proofInstructionOffset": proof_instruction_offset,
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
let mut source_accounts: Vec<String> = vec![];
|
||||
let first_source_account_index = account_indexes
|
||||
.len()
|
||||
.saturating_sub(num_token_accounts as usize);
|
||||
for i in account_indexes[first_source_account_index..].iter() {
|
||||
source_accounts.push(account_keys[*i as usize].to_string());
|
||||
if transfer_data.close_split_context_state_on_execution.into() {
|
||||
map.insert(
|
||||
"lamportDestination".to_string(),
|
||||
json!(account_keys[account_indexes[7] as usize].to_string()),
|
||||
);
|
||||
map.insert(
|
||||
"contextStateOwner".to_string(),
|
||||
json!(account_keys[account_indexes[8] as usize].to_string()),
|
||||
);
|
||||
}
|
||||
map.insert("sourceAccounts".to_string(), json!(source_accounts));
|
||||
parse_signers(
|
||||
map,
|
||||
3,
|
||||
account_keys,
|
||||
&account_indexes[..first_source_account_index],
|
||||
"withdrawWithheldAuthority",
|
||||
"multisigWithdrawWithheldAuthority",
|
||||
);
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "withdrawWithheldConfidentialTransferTokensFromAccounts"
|
||||
.to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
ConfidentialTransferInstruction::HarvestWithheldTokensToMint => {
|
||||
check_num_token_accounts(account_indexes, 1)?;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
let mut source_accounts: Vec<String> = vec![];
|
||||
for i in account_indexes.iter().skip(1) {
|
||||
source_accounts.push(account_keys[*i as usize].to_string());
|
||||
}
|
||||
map.insert("sourceAccounts".to_string(), json!(source_accounts));
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "harvestWithheldConfidentialTransferTokensToMint".to_string(),
|
||||
instruction_type: "confidentialTransferWithSplitProofs".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
use {
|
||||
super::*,
|
||||
solana_account_decoder::parse_token_extension::UiConfidentialTransferFeeConfig,
|
||||
spl_token_2022::{
|
||||
extension::confidential_transfer_fee::{instruction::*, ConfidentialTransferFeeConfig},
|
||||
instruction::{decode_instruction_data, decode_instruction_type},
|
||||
},
|
||||
};
|
||||
|
||||
pub(in crate::parse_token) fn parse_confidential_transfer_fee_instruction(
|
||||
instruction_data: &[u8],
|
||||
account_indexes: &[u8],
|
||||
account_keys: &AccountKeys,
|
||||
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
|
||||
match decode_instruction_type(instruction_data)
|
||||
.map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken))?
|
||||
{
|
||||
ConfidentialTransferFeeInstruction::InitializeConfidentialTransferFeeConfig => {
|
||||
check_num_token_accounts(account_indexes, 1)?;
|
||||
let confidential_transfer_mint: ConfidentialTransferFeeConfig =
|
||||
*decode_instruction_data(instruction_data).map_err(|_| {
|
||||
ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
|
||||
})?;
|
||||
let confidential_transfer_mint: UiConfidentialTransferFeeConfig =
|
||||
confidential_transfer_mint.into();
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
map.append(json!(confidential_transfer_mint).as_object_mut().unwrap());
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "initializeConfidentialTransferFeeConfig".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
ConfidentialTransferFeeInstruction::WithdrawWithheldTokensFromMint => {
|
||||
check_num_token_accounts(account_indexes, 4)?;
|
||||
let withdraw_withheld_data: WithdrawWithheldTokensFromMintData =
|
||||
*decode_instruction_data(instruction_data).map_err(|_| {
|
||||
ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
|
||||
})?;
|
||||
let proof_instruction_offset: i8 = withdraw_withheld_data.proof_instruction_offset;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
"feeRecipient": account_keys[account_indexes[1] as usize].to_string(),
|
||||
"instructionsSysvar": account_keys[account_indexes[2] as usize].to_string(),
|
||||
"proofInstructionOffset": proof_instruction_offset,
|
||||
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
parse_signers(
|
||||
map,
|
||||
3,
|
||||
account_keys,
|
||||
account_indexes,
|
||||
"withdrawWithheldAuthority",
|
||||
"multisigWithdrawWithheldAuthority",
|
||||
);
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "withdrawWithheldConfidentialTransferTokensFromMint".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
ConfidentialTransferFeeInstruction::WithdrawWithheldTokensFromAccounts => {
|
||||
let withdraw_withheld_data: WithdrawWithheldTokensFromAccountsData =
|
||||
*decode_instruction_data(instruction_data).map_err(|_| {
|
||||
ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
|
||||
})?;
|
||||
let num_token_accounts = withdraw_withheld_data.num_token_accounts;
|
||||
check_num_token_accounts(account_indexes, 4 + num_token_accounts as usize)?;
|
||||
let proof_instruction_offset: i8 = withdraw_withheld_data.proof_instruction_offset;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
"feeRecipient": account_keys[account_indexes[1] as usize].to_string(),
|
||||
"instructionsSysvar": account_keys[account_indexes[2] as usize].to_string(),
|
||||
"proofInstructionOffset": proof_instruction_offset,
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
let mut source_accounts: Vec<String> = vec![];
|
||||
let first_source_account_index = account_indexes
|
||||
.len()
|
||||
.saturating_sub(num_token_accounts as usize);
|
||||
for i in account_indexes[first_source_account_index..].iter() {
|
||||
source_accounts.push(account_keys[*i as usize].to_string());
|
||||
}
|
||||
map.insert("sourceAccounts".to_string(), json!(source_accounts));
|
||||
parse_signers(
|
||||
map,
|
||||
3,
|
||||
account_keys,
|
||||
&account_indexes[..first_source_account_index],
|
||||
"withdrawWithheldAuthority",
|
||||
"multisigWithdrawWithheldAuthority",
|
||||
);
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "withdrawWithheldConfidentialTransferTokensFromAccounts"
|
||||
.to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
ConfidentialTransferFeeInstruction::HarvestWithheldTokensToMint => {
|
||||
check_num_token_accounts(account_indexes, 1)?;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
let mut source_accounts: Vec<String> = vec![];
|
||||
for i in account_indexes.iter().skip(1) {
|
||||
source_accounts.push(account_keys[*i as usize].to_string());
|
||||
}
|
||||
map.insert("sourceAccounts".to_string(), json!(source_accounts));
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "harvestWithheldConfidentialTransferTokensToMint".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
ConfidentialTransferFeeInstruction::EnableHarvestToMint => {
|
||||
check_num_token_accounts(account_indexes, 2)?;
|
||||
let mut value = json!({
|
||||
"account": account_keys[account_indexes[0] as usize].to_string(),
|
||||
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
parse_signers(
|
||||
map,
|
||||
1,
|
||||
account_keys,
|
||||
account_indexes,
|
||||
"owner",
|
||||
"multisigOwner",
|
||||
);
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "enableConfidentialTransferFeeHarvestToMint".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
ConfidentialTransferFeeInstruction::DisableHarvestToMint => {
|
||||
check_num_token_accounts(account_indexes, 2)?;
|
||||
let mut value = json!({
|
||||
"account": account_keys[account_indexes[0] as usize].to_string(),
|
||||
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
parse_signers(
|
||||
map,
|
||||
1,
|
||||
account_keys,
|
||||
account_indexes,
|
||||
"owner",
|
||||
"multisigOwner",
|
||||
);
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "disableConfidentialTransferFeeHarvestToMint".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
use {
|
||||
super::*,
|
||||
spl_token_2022::{
|
||||
extension::metadata_pointer::instruction::*,
|
||||
instruction::{decode_instruction_data, decode_instruction_type},
|
||||
},
|
||||
};
|
||||
|
||||
pub(in crate::parse_token) fn parse_metadata_pointer_instruction(
|
||||
instruction_data: &[u8],
|
||||
account_indexes: &[u8],
|
||||
account_keys: &AccountKeys,
|
||||
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
|
||||
match decode_instruction_type(instruction_data)
|
||||
.map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken))?
|
||||
{
|
||||
MetadataPointerInstruction::Initialize => {
|
||||
check_num_token_accounts(account_indexes, 1)?;
|
||||
let InitializeInstructionData {
|
||||
authority,
|
||||
metadata_address,
|
||||
} = *decode_instruction_data(instruction_data).map_err(|_| {
|
||||
ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
|
||||
})?;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
if let Some(authority) = Option::<Pubkey>::from(authority) {
|
||||
map.insert("authority".to_string(), json!(authority.to_string()));
|
||||
}
|
||||
if let Some(metadata_address) = Option::<Pubkey>::from(metadata_address) {
|
||||
map.insert(
|
||||
"metadataAddress".to_string(),
|
||||
json!(metadata_address.to_string()),
|
||||
);
|
||||
}
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "initializeMetadataPointer".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
MetadataPointerInstruction::Update => {
|
||||
check_num_token_accounts(account_indexes, 2)?;
|
||||
let UpdateInstructionData { metadata_address } =
|
||||
*decode_instruction_data(instruction_data).map_err(|_| {
|
||||
ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
|
||||
})?;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
if let Some(metadata_address) = Option::<Pubkey>::from(metadata_address) {
|
||||
map.insert(
|
||||
"metadataAddress".to_string(),
|
||||
json!(metadata_address.to_string()),
|
||||
);
|
||||
}
|
||||
parse_signers(
|
||||
map,
|
||||
1,
|
||||
account_keys,
|
||||
account_indexes,
|
||||
"authority",
|
||||
"multisigAuthority",
|
||||
);
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "updateMetadataPointer".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use {
|
||||
super::*, crate::parse_token::test::*, solana_sdk::pubkey::Pubkey,
|
||||
spl_token_2022::solana_program::message::Message,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_parse_metadata_pointer_instruction() {
|
||||
let mint_pubkey = Pubkey::new_unique();
|
||||
let authority = Pubkey::new_unique();
|
||||
let metadata_address = Pubkey::new_unique();
|
||||
|
||||
// Initialize variations
|
||||
let init_ix = initialize(
|
||||
&spl_token_2022::id(),
|
||||
&mint_pubkey,
|
||||
Some(authority),
|
||||
Some(metadata_address),
|
||||
)
|
||||
.unwrap();
|
||||
let message = Message::new(&[init_ix], None);
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(
|
||||
&compiled_instruction,
|
||||
&AccountKeys::new(&message.account_keys, None)
|
||||
)
|
||||
.unwrap(),
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "initializeMetadataPointer".to_string(),
|
||||
info: json!({
|
||||
"mint": mint_pubkey.to_string(),
|
||||
"authority": authority.to_string(),
|
||||
"metadataAddress": metadata_address.to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
let init_ix = initialize(&spl_token_2022::id(), &mint_pubkey, None, None).unwrap();
|
||||
let message = Message::new(&[init_ix], None);
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(
|
||||
&compiled_instruction,
|
||||
&AccountKeys::new(&message.account_keys, None)
|
||||
)
|
||||
.unwrap(),
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "initializeMetadataPointer".to_string(),
|
||||
info: json!({
|
||||
"mint": mint_pubkey.to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Single owner Update
|
||||
let update_ix = update(
|
||||
&spl_token_2022::id(),
|
||||
&mint_pubkey,
|
||||
&authority,
|
||||
&[],
|
||||
Some(metadata_address),
|
||||
)
|
||||
.unwrap();
|
||||
let message = Message::new(&[update_ix], None);
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(
|
||||
&compiled_instruction,
|
||||
&AccountKeys::new(&message.account_keys, None)
|
||||
)
|
||||
.unwrap(),
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "updateMetadataPointer".to_string(),
|
||||
info: json!({
|
||||
"mint": mint_pubkey.to_string(),
|
||||
"authority": authority.to_string(),
|
||||
"metadataAddress": metadata_address.to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Multisig Update
|
||||
let multisig_pubkey = Pubkey::new_unique();
|
||||
let multisig_signer0 = Pubkey::new_unique();
|
||||
let multisig_signer1 = Pubkey::new_unique();
|
||||
let update_ix = update(
|
||||
&spl_token_2022::id(),
|
||||
&mint_pubkey,
|
||||
&multisig_pubkey,
|
||||
&[&multisig_signer0, &multisig_signer1],
|
||||
Some(metadata_address),
|
||||
)
|
||||
.unwrap();
|
||||
let message = Message::new(&[update_ix], None);
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(
|
||||
&compiled_instruction,
|
||||
&AccountKeys::new(&message.account_keys, None)
|
||||
)
|
||||
.unwrap(),
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "updateMetadataPointer".to_string(),
|
||||
info: json!({
|
||||
"mint": mint_pubkey.to_string(),
|
||||
"metadataAddress": metadata_address.to_string(),
|
||||
"multisigAuthority": multisig_pubkey.to_string(),
|
||||
"signers": vec![
|
||||
multisig_signer0.to_string(),
|
||||
multisig_signer1.to_string(),
|
||||
],
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
use super::*;
|
||||
|
||||
pub(super) mod confidential_transfer;
|
||||
pub(super) mod confidential_transfer_fee;
|
||||
pub(super) mod cpi_guard;
|
||||
pub(super) mod default_account_state;
|
||||
pub(super) mod interest_bearing_mint;
|
||||
pub(super) mod memo_transfer;
|
||||
pub(super) mod metadata_pointer;
|
||||
pub(super) mod mint_close_authority;
|
||||
pub(super) mod permanent_delegate;
|
||||
pub(super) mod reallocate;
|
||||
pub(super) mod transfer_fee;
|
||||
pub(super) mod transfer_hook;
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
use {
|
||||
super::*,
|
||||
spl_token_2022::{
|
||||
extension::transfer_hook::instruction::*,
|
||||
instruction::{decode_instruction_data, decode_instruction_type},
|
||||
},
|
||||
};
|
||||
|
||||
pub(in crate::parse_token) fn parse_transfer_hook_instruction(
|
||||
instruction_data: &[u8],
|
||||
account_indexes: &[u8],
|
||||
account_keys: &AccountKeys,
|
||||
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
|
||||
match decode_instruction_type(instruction_data)
|
||||
.map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken))?
|
||||
{
|
||||
TransferHookInstruction::Initialize => {
|
||||
check_num_token_accounts(account_indexes, 1)?;
|
||||
let InitializeInstructionData {
|
||||
authority,
|
||||
program_id,
|
||||
} = *decode_instruction_data(instruction_data).map_err(|_| {
|
||||
ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
|
||||
})?;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
if let Some(authority) = Option::<Pubkey>::from(authority) {
|
||||
map.insert("authority".to_string(), json!(authority.to_string()));
|
||||
}
|
||||
if let Some(program_id) = Option::<Pubkey>::from(program_id) {
|
||||
map.insert("programId".to_string(), json!(program_id.to_string()));
|
||||
}
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "initializeTransferHook".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
TransferHookInstruction::Update => {
|
||||
check_num_token_accounts(account_indexes, 2)?;
|
||||
let UpdateInstructionData { program_id } = *decode_instruction_data(instruction_data)
|
||||
.map_err(|_| {
|
||||
ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken)
|
||||
})?;
|
||||
let mut value = json!({
|
||||
"mint": account_keys[account_indexes[0] as usize].to_string(),
|
||||
});
|
||||
let map = value.as_object_mut().unwrap();
|
||||
if let Some(program_id) = Option::<Pubkey>::from(program_id) {
|
||||
map.insert("programId".to_string(), json!(program_id.to_string()));
|
||||
}
|
||||
parse_signers(
|
||||
map,
|
||||
1,
|
||||
account_keys,
|
||||
account_indexes,
|
||||
"authority",
|
||||
"multisigAuthority",
|
||||
);
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "updateTransferHook".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use {
|
||||
super::*, crate::parse_token::test::*, solana_sdk::pubkey::Pubkey,
|
||||
spl_token_2022::solana_program::message::Message,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_parse_transfer_hook_instruction() {
|
||||
let mint_pubkey = Pubkey::new_unique();
|
||||
let authority = Pubkey::new_unique();
|
||||
let program_id = Pubkey::new_unique();
|
||||
|
||||
// Initialize variations
|
||||
let init_ix = initialize(
|
||||
&spl_token_2022::id(),
|
||||
&mint_pubkey,
|
||||
Some(authority),
|
||||
Some(program_id),
|
||||
)
|
||||
.unwrap();
|
||||
let message = Message::new(&[init_ix], None);
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(
|
||||
&compiled_instruction,
|
||||
&AccountKeys::new(&message.account_keys, None)
|
||||
)
|
||||
.unwrap(),
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "initializeTransferHook".to_string(),
|
||||
info: json!({
|
||||
"mint": mint_pubkey.to_string(),
|
||||
"authority": authority.to_string(),
|
||||
"programId": program_id.to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
let init_ix = initialize(&spl_token_2022::id(), &mint_pubkey, None, None).unwrap();
|
||||
let message = Message::new(&[init_ix], None);
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(
|
||||
&compiled_instruction,
|
||||
&AccountKeys::new(&message.account_keys, None)
|
||||
)
|
||||
.unwrap(),
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "initializeTransferHook".to_string(),
|
||||
info: json!({
|
||||
"mint": mint_pubkey.to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Single owner Update
|
||||
let update_ix = update(
|
||||
&spl_token_2022::id(),
|
||||
&mint_pubkey,
|
||||
&authority,
|
||||
&[],
|
||||
Some(program_id),
|
||||
)
|
||||
.unwrap();
|
||||
let message = Message::new(&[update_ix], None);
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(
|
||||
&compiled_instruction,
|
||||
&AccountKeys::new(&message.account_keys, None)
|
||||
)
|
||||
.unwrap(),
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "updateTransferHook".to_string(),
|
||||
info: json!({
|
||||
"mint": mint_pubkey.to_string(),
|
||||
"authority": authority.to_string(),
|
||||
"programId": program_id.to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Multisig Update
|
||||
let multisig_pubkey = Pubkey::new_unique();
|
||||
let multisig_signer0 = Pubkey::new_unique();
|
||||
let multisig_signer1 = Pubkey::new_unique();
|
||||
let update_ix = update(
|
||||
&spl_token_2022::id(),
|
||||
&mint_pubkey,
|
||||
&multisig_pubkey,
|
||||
&[&multisig_signer0, &multisig_signer1],
|
||||
Some(program_id),
|
||||
)
|
||||
.unwrap();
|
||||
let message = Message::new(&[update_ix], None);
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(
|
||||
&compiled_instruction,
|
||||
&AccountKeys::new(&message.account_keys, None)
|
||||
)
|
||||
.unwrap(),
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "updateTransferHook".to_string(),
|
||||
info: json!({
|
||||
"mint": mint_pubkey.to_string(),
|
||||
"programId": program_id.to_string(),
|
||||
"multisigAuthority": multisig_pubkey.to_string(),
|
||||
"signers": vec![
|
||||
multisig_signer0.to_string(),
|
||||
multisig_signer1.to_string(),
|
||||
],
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue