diff --git a/rust/chains/tw_solana/src/defined_addresses.rs b/rust/chains/tw_solana/src/defined_addresses.rs index 4047605b435..f7e663ef1f4 100644 --- a/rust/chains/tw_solana/src/defined_addresses.rs +++ b/rust/chains/tw_solana/src/defined_addresses.rs @@ -16,6 +16,7 @@ macro_rules! define { define!(SYSTEM_PROGRAM_ID_ADDRESS = "11111111111111111111111111111111"); define!(STAKE_PROGRAM_ID_ADDRESS = "Stake11111111111111111111111111111111111111"); define!(TOKEN_PROGRAM_ID_ADDRESS = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); +define!(TOKEN_2022_PROGRAM_ID_ADDRESS = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"); define!(ASSOCIATED_TOKEN_PROGRAM_ID_ADDRESS = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"); define!(SYSVAR_RENT_ID_ADDRESS = "SysvarRent111111111111111111111111111111111"); define!(SYSVAR_CLOCK_ID_ADDRESS = "SysvarC1ock11111111111111111111111111111111"); diff --git a/rust/chains/tw_solana/src/modules/compiled_keys.rs b/rust/chains/tw_solana/src/modules/compiled_keys.rs index e138c1d9b29..2ab0c88c207 100644 --- a/rust/chains/tw_solana/src/modules/compiled_keys.rs +++ b/rust/chains/tw_solana/src/modules/compiled_keys.rs @@ -81,18 +81,21 @@ impl CompiledKeys { (meta.is_signer == is_signer && meta.is_writable == is_writable).then_some(*account) }; - let writable_signer_keys: Vec = ordered_keys + let mut writable_signer_keys: Vec = ordered_keys .iter() .filter_map(|key| filter(key, true, true)) .collect(); - let readonly_signer_keys: Vec = ordered_keys + writable_signer_keys.sort(); + let mut readonly_signer_keys: Vec = ordered_keys .iter() .filter_map(|key| filter(key, true, false)) .collect(); - let writable_non_signer_keys: Vec = ordered_keys + readonly_signer_keys.sort(); + let mut writable_non_signer_keys: Vec = ordered_keys .iter() .filter_map(|key| filter(key, false, true)) .collect(); + writable_non_signer_keys.sort(); let readonly_non_signer_keys: Vec = ordered_keys .iter() .filter_map(|key| filter(key, false, false)) diff --git a/rust/chains/tw_solana/src/modules/instruction_builder/token_instruction.rs b/rust/chains/tw_solana/src/modules/instruction_builder/token_instruction.rs index 8cfb3248bad..1224b686b12 100644 --- a/rust/chains/tw_solana/src/modules/instruction_builder/token_instruction.rs +++ b/rust/chains/tw_solana/src/modules/instruction_builder/token_instruction.rs @@ -74,6 +74,7 @@ impl TokenInstructionBuilder { other_main_pubkey: SolanaAddress, token_mint_pubkey: SolanaAddress, token_pubkey: SolanaAddress, + is_token_2022: bool, ) -> Instruction { let account_metas = vec![ AccountMeta::new(funding_pubkey, true), @@ -81,7 +82,7 @@ impl TokenInstructionBuilder { AccountMeta::readonly(other_main_pubkey, false), AccountMeta::readonly(token_mint_pubkey, false), AccountMeta::readonly(*SYSTEM_PROGRAM_ID_ADDRESS, false), - AccountMeta::readonly(*TOKEN_PROGRAM_ID_ADDRESS, false), + AccountMeta::readonly(if is_token_2022 { *TOKEN_2022_PROGRAM_ID_ADDRESS } else { *TOKEN_PROGRAM_ID_ADDRESS }, false), AccountMeta::readonly(*SYSVAR_RENT_ID_ADDRESS, false), ]; let data = Data::default(); @@ -96,15 +97,16 @@ impl TokenInstructionBuilder { signer: SolanaAddress, amount: u64, decimals: u8, + is_token_2022: bool, ) -> Instruction { let account_metas = vec![ AccountMeta::new(sender_token_pubkey, false), AccountMeta::readonly(token_mint_pubkey, false), AccountMeta::new(recipient_token_pubkey, false), - AccountMeta::new(signer, true), + AccountMeta::readonly(signer, true), ]; let data = TokenInstruction::TransferChecked { amount, decimals }.pack(); - Instruction::new(*TOKEN_PROGRAM_ID_ADDRESS, data, account_metas) + Instruction::new(if is_token_2022 { *TOKEN_2022_PROGRAM_ID_ADDRESS } else { *TOKEN_PROGRAM_ID_ADDRESS }, data, account_metas) } } diff --git a/rust/chains/tw_solana/src/modules/message_builder.rs b/rust/chains/tw_solana/src/modules/message_builder.rs index 0ce11d8b67a..735c1ebbe40 100644 --- a/rust/chains/tw_solana/src/modules/message_builder.rs +++ b/rust/chains/tw_solana/src/modules/message_builder.rs @@ -333,6 +333,7 @@ impl<'a> MessageBuilder<'a> { other_main_address, token_mint_address, token_address, + create_token_acc.is_token_2022 ); let mut builder = InstructionBuilder::default(); builder @@ -378,6 +379,7 @@ impl<'a> MessageBuilder<'a> { signer, token_transfer.amount, decimals, + token_transfer.is_token_2022 ) .with_references(references); @@ -432,6 +434,7 @@ impl<'a> MessageBuilder<'a> { recipient_main_address, token_mint_address, recipient_token_address, + create_and_transfer.is_token_2022 ); let transfer_instruction = TokenInstructionBuilder::transfer_checked( sender_token_address, @@ -440,6 +443,7 @@ impl<'a> MessageBuilder<'a> { signer, create_and_transfer.amount, decimals, + create_and_transfer.is_token_2022 ) .with_references(references); diff --git a/rust/tw_any_coin/tests/chains/solana/solana_sign.rs b/rust/tw_any_coin/tests/chains/solana/solana_sign.rs index f59c1fd74bf..182d94a5320 100644 --- a/rust/tw_any_coin/tests/chains/solana/solana_sign.rs +++ b/rust/tw_any_coin/tests/chains/solana/solana_sign.rs @@ -392,6 +392,7 @@ fn test_solana_sign_create_token_account() { main_address: "B1iGmDJdvmxyUiYM8UEo2Uw2D58EmUrw4KyLYMmrhf8V".into(), token_mint_address: "SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt".into(), token_address: "EDNd1ycsydWYwVmrYZvqYazFqwk1QjBgAUKFjBoz1jKP".into(), + is_token_2022: false }; let input = Proto::SigningInput { private_key: b58("9YtuoD4sH4h88CVM8DSnkfoAaLY7YeGC2TarDJ8eyMS5"), @@ -413,6 +414,7 @@ fn test_solana_sign_create_token_account_5ktpn1() { main_address: "Eg5jqooyG6ySaXKbQUu4Lpvu2SqUPZrNkM4zXs9iUDLJ".into(), token_mint_address: "SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt".into(), token_address: "ANVCrmRw7Ww7rTFfMbrjApSPXEEcZpBa6YEiBdf98pAf".into(), + is_token_2022: false }; let input = Proto::SigningInput { private_key: "4b9d6f57d28b06cbfa1d4cc710953e62d653caf853415c56ffd9d150acdeb7f7" @@ -438,6 +440,7 @@ fn test_solana_sign_create_token_account_for_other_3e6ufv() { main_address: "3xJ3MoUVFPNFEHfWdtNFa8ajXUHsJPzXcBSWMKLd76ft".into(), token_mint_address: "SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt".into(), token_address: "67BrwFYt7qUnbAcYBVx7sQ4jeD2KWN1ohP6bMikmmQV3".into(), + is_token_2022: false }; let input = Proto::SigningInput { private_key: "4b9d6f57d28b06cbfa1d4cc710953e62d653caf853415c56ffd9d150acdeb7f7" @@ -469,6 +472,7 @@ fn test_solana_sign_create_token_account_with_priority_fee_price() { // WBTC token_mint_address: "3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh".into(), token_address: "94JfTH8qCeBQDBatvULREG43msjSQscT7oHnqx7jppX".into(), + is_token_2022: false }; let input = Proto::SigningInput { @@ -496,6 +500,7 @@ fn test_solana_sign_token_transfer() { // 0.004 amount: 4000, decimals: 6, + is_token_2022: false, ..Proto::TokenTransfer::default() }; let input = Proto::SigningInput { @@ -522,6 +527,7 @@ fn test_solana_sign_token_transfer_2pmvzp() { // 0.0061 amount: 6100, decimals: 6, + is_token_2022: false, ..Proto::TokenTransfer::default() }; let input = Proto::SigningInput { @@ -549,6 +555,7 @@ fn test_solana_sign_create_and_transfer_token() { // 0.0029 amount: 2900, decimals: 6, + is_token_2022: false, ..Proto::CreateAndTransferToken::default() }; let input = Proto::SigningInput { @@ -578,6 +585,7 @@ fn test_solana_sign_create_and_transfer_token_2() { // 0.004 amount: 4000, decimals: 6, + is_token_2022: false, ..Proto::CreateAndTransferToken::default() }; let input = Proto::SigningInput { @@ -611,6 +619,7 @@ fn test_solana_sign_create_and_transfer_token_with_memo_and_references() { "CuieVDEDtLo7FypA9SbLM9saXFdb1dsshEkyErMqkRQq".into(), "tFpP7tZUt6zb7YZPpQ11kXNmsc5YzpMXmahGMvCHhqS".into(), ], + is_token_2022: false }; let input = Proto::SigningInput { private_key: b58("66ApBuKpo2uSzpjGBraHq7HP8UZMUJzp3um8FdEjkC9c"), @@ -638,6 +647,7 @@ fn test_solana_sign_create_and_transfer_token_with_durable_nonce() { // 0.004 amount: 4000, decimals: 6, + is_token_2022: false, ..Proto::CreateAndTransferToken::default() }; let input = Proto::SigningInput { diff --git a/src/proto/Solana.proto b/src/proto/Solana.proto index 24a411c8002..a6d182c54c6 100644 --- a/src/proto/Solana.proto +++ b/src/proto/Solana.proto @@ -79,6 +79,9 @@ message CreateTokenAccount { // Token address string token_address = 3; + + // optional is token 2022 + bool is_token_2022 = 4; } // Transfer tokens @@ -103,6 +106,9 @@ message TokenTransfer { // optional referenced public keys repeated string references = 7; + + // optional is token 2022 + bool is_token_2022 = 8; } // CreateTokenAccount and TokenTransfer combined @@ -130,6 +136,9 @@ message CreateAndTransferToken { // optional referenced public keys repeated string references = 8; + + // optional is token 2022 + bool is_token_2022 = 9; } message CreateNonceAccount {