From f3d2024fd8709ef5f89bfbde1fa7ed8710cf9a31 Mon Sep 17 00:00:00 2001 From: billythedummy Date: Wed, 17 Jan 2024 18:57:51 +0800 Subject: [PATCH] update IDL --- interfaces/README.md | 2 +- .../stakedex_deposit_sol_interface/Cargo.toml | 6 +- .../src/instructions.rs | 177 ++- .../Cargo.toml | 6 +- .../src/instructions.rs | 237 ++- interfaces/stakedex_interface/Cargo.toml | 12 +- interfaces/stakedex_interface/idl.json | 286 +++- interfaces/stakedex_interface/src/errors.rs | 2 + .../stakedex_interface/src/instructions.rs | 1305 +++++++++++++++-- interfaces/stakedex_interface/src/lib.rs | 2 + interfaces/stakedex_interface/src/typedefs.rs | 7 + .../Cargo.toml | 6 +- .../idl.json | 20 + .../src/instructions.rs | 281 +++- stakedex_sdk/README.md | 2 +- stakedex_sdk/src/lib.rs | 10 +- 16 files changed, 2038 insertions(+), 323 deletions(-) create mode 100644 interfaces/stakedex_interface/src/typedefs.rs diff --git a/interfaces/README.md b/interfaces/README.md index c4aadd5..a952e64 100644 --- a/interfaces/README.md +++ b/interfaces/README.md @@ -2,4 +2,4 @@ This folder contains generated on-chain program interfaces. -All crates generated by [`solores v0.5.0`](https://docs.rs/solores/0.5.0/solores/) +All crates generated by [`solores v0.7.0`](https://docs.rs/solores/0.7.0/solores/) diff --git a/interfaces/stakedex_deposit_sol_interface/Cargo.toml b/interfaces/stakedex_deposit_sol_interface/Cargo.toml index e266b39..a1b18b3 100644 --- a/interfaces/stakedex_deposit_sol_interface/Cargo.toml +++ b/interfaces/stakedex_deposit_sol_interface/Cargo.toml @@ -6,9 +6,9 @@ edition = "2021" [dependencies.borsh] workspace = true -[dependencies.solana-program] -workspace = true - [dependencies.serde] optional = true workspace = true + +[dependencies.solana-program] +workspace = true diff --git a/interfaces/stakedex_deposit_sol_interface/src/instructions.rs b/interfaces/stakedex_deposit_sol_interface/src/instructions.rs index 622e35d..6476179 100644 --- a/interfaces/stakedex_deposit_sol_interface/src/instructions.rs +++ b/interfaces/stakedex_deposit_sol_interface/src/instructions.rs @@ -46,6 +46,21 @@ impl StakedexDepositSolProgramIx { Ok(data) } } +fn invoke_instruction<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>( + ix: &Instruction, + accounts: A, +) -> ProgramResult { + let account_info: [AccountInfo<'info>; N] = accounts.into(); + invoke(ix, &account_info) +} +fn invoke_instruction_signed<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>( + ix: &Instruction, + accounts: A, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let account_info: [AccountInfo<'info>; N] = accounts.into(); + invoke_signed(ix, &account_info, seeds) +} pub const MARINADE_DEPOSIT_SOL_IX_ACCOUNTS_LEN: usize = 7; #[derive(Copy, Clone, Debug)] pub struct MarinadeDepositSolAccounts<'me, 'info> { @@ -193,31 +208,45 @@ impl MarinadeDepositSolIxData { Ok(data) } } -pub fn marinade_deposit_sol_ix>( - accounts: K, +pub fn marinade_deposit_sol_ix_with_program_id( + program_id: Pubkey, + keys: MarinadeDepositSolKeys, ) -> std::io::Result { - let keys: MarinadeDepositSolKeys = accounts.into(); let metas: [AccountMeta; MARINADE_DEPOSIT_SOL_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: MarinadeDepositSolIxData.try_to_vec()?, }) } -pub fn marinade_deposit_sol_invoke<'info>( - accounts: MarinadeDepositSolAccounts<'_, 'info>, +pub fn marinade_deposit_sol_ix(keys: MarinadeDepositSolKeys) -> std::io::Result { + marinade_deposit_sol_ix_with_program_id(crate::ID, keys) +} +pub fn marinade_deposit_sol_invoke_with_program_id( + program_id: Pubkey, + accounts: MarinadeDepositSolAccounts<'_, '_>, ) -> ProgramResult { - let ix = marinade_deposit_sol_ix(accounts)?; - let account_info: [AccountInfo<'info>; MARINADE_DEPOSIT_SOL_IX_ACCOUNTS_LEN] = accounts.into(); - invoke(&ix, &account_info) + let keys: MarinadeDepositSolKeys = accounts.into(); + let ix = marinade_deposit_sol_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn marinade_deposit_sol_invoke(accounts: MarinadeDepositSolAccounts<'_, '_>) -> ProgramResult { + marinade_deposit_sol_invoke_with_program_id(crate::ID, accounts) +} +pub fn marinade_deposit_sol_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: MarinadeDepositSolAccounts<'_, '_>, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let keys: MarinadeDepositSolKeys = accounts.into(); + let ix = marinade_deposit_sol_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn marinade_deposit_sol_invoke_signed<'info>( - accounts: MarinadeDepositSolAccounts<'_, 'info>, +pub fn marinade_deposit_sol_invoke_signed( + accounts: MarinadeDepositSolAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = marinade_deposit_sol_ix(accounts)?; - let account_info: [AccountInfo<'info>; MARINADE_DEPOSIT_SOL_IX_ACCOUNTS_LEN] = accounts.into(); - invoke_signed(&ix, &account_info, seeds) + marinade_deposit_sol_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn marinade_deposit_sol_verify_account_keys( accounts: MarinadeDepositSolAccounts<'_, '_>, @@ -247,7 +276,7 @@ pub fn marinade_deposit_sol_verify_account_keys( } Ok(()) } -pub fn marinade_deposit_sol_verify_account_privileges<'me, 'info>( +pub fn marinade_deposit_sol_verify_writable_privileges<'me, 'info>( accounts: MarinadeDepositSolAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -262,6 +291,12 @@ pub fn marinade_deposit_sol_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn marinade_deposit_sol_verify_account_privileges<'me, 'info>( + accounts: MarinadeDepositSolAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + marinade_deposit_sol_verify_writable_privileges(accounts)?; + Ok(()) +} pub const SOCEAN_STAKE_POOL_DEPOSIT_SOL_IX_ACCOUNTS_LEN: usize = 6; #[derive(Copy, Clone, Debug)] pub struct SoceanStakePoolDepositSolAccounts<'me, 'info> { @@ -402,33 +437,49 @@ impl SoceanStakePoolDepositSolIxData { Ok(data) } } -pub fn socean_stake_pool_deposit_sol_ix>( - accounts: K, +pub fn socean_stake_pool_deposit_sol_ix_with_program_id( + program_id: Pubkey, + keys: SoceanStakePoolDepositSolKeys, ) -> std::io::Result { - let keys: SoceanStakePoolDepositSolKeys = accounts.into(); let metas: [AccountMeta; SOCEAN_STAKE_POOL_DEPOSIT_SOL_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: SoceanStakePoolDepositSolIxData.try_to_vec()?, }) } -pub fn socean_stake_pool_deposit_sol_invoke<'info>( - accounts: SoceanStakePoolDepositSolAccounts<'_, 'info>, +pub fn socean_stake_pool_deposit_sol_ix( + keys: SoceanStakePoolDepositSolKeys, +) -> std::io::Result { + socean_stake_pool_deposit_sol_ix_with_program_id(crate::ID, keys) +} +pub fn socean_stake_pool_deposit_sol_invoke_with_program_id( + program_id: Pubkey, + accounts: SoceanStakePoolDepositSolAccounts<'_, '_>, +) -> ProgramResult { + let keys: SoceanStakePoolDepositSolKeys = accounts.into(); + let ix = socean_stake_pool_deposit_sol_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn socean_stake_pool_deposit_sol_invoke( + accounts: SoceanStakePoolDepositSolAccounts<'_, '_>, ) -> ProgramResult { - let ix = socean_stake_pool_deposit_sol_ix(accounts)?; - let account_info: [AccountInfo<'info>; SOCEAN_STAKE_POOL_DEPOSIT_SOL_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + socean_stake_pool_deposit_sol_invoke_with_program_id(crate::ID, accounts) } -pub fn socean_stake_pool_deposit_sol_invoke_signed<'info>( - accounts: SoceanStakePoolDepositSolAccounts<'_, 'info>, +pub fn socean_stake_pool_deposit_sol_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: SoceanStakePoolDepositSolAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = socean_stake_pool_deposit_sol_ix(accounts)?; - let account_info: [AccountInfo<'info>; SOCEAN_STAKE_POOL_DEPOSIT_SOL_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + let keys: SoceanStakePoolDepositSolKeys = accounts.into(); + let ix = socean_stake_pool_deposit_sol_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) +} +pub fn socean_stake_pool_deposit_sol_invoke_signed( + accounts: SoceanStakePoolDepositSolAccounts<'_, '_>, + seeds: &[&[&[u8]]], +) -> ProgramResult { + socean_stake_pool_deposit_sol_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn socean_stake_pool_deposit_sol_verify_account_keys( accounts: SoceanStakePoolDepositSolAccounts<'_, '_>, @@ -460,7 +511,7 @@ pub fn socean_stake_pool_deposit_sol_verify_account_keys( } Ok(()) } -pub fn socean_stake_pool_deposit_sol_verify_account_privileges<'me, 'info>( +pub fn socean_stake_pool_deposit_sol_verify_writable_privileges<'me, 'info>( accounts: SoceanStakePoolDepositSolAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -474,6 +525,12 @@ pub fn socean_stake_pool_deposit_sol_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn socean_stake_pool_deposit_sol_verify_account_privileges<'me, 'info>( + accounts: SoceanStakePoolDepositSolAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + socean_stake_pool_deposit_sol_verify_writable_privileges(accounts)?; + Ok(()) +} pub const SPL_STAKE_POOL_DEPOSIT_SOL_IX_ACCOUNTS_LEN: usize = 5; #[derive(Copy, Clone, Debug)] pub struct SplStakePoolDepositSolAccounts<'me, 'info> { @@ -601,33 +658,49 @@ impl SplStakePoolDepositSolIxData { Ok(data) } } -pub fn spl_stake_pool_deposit_sol_ix>( - accounts: K, +pub fn spl_stake_pool_deposit_sol_ix_with_program_id( + program_id: Pubkey, + keys: SplStakePoolDepositSolKeys, ) -> std::io::Result { - let keys: SplStakePoolDepositSolKeys = accounts.into(); let metas: [AccountMeta; SPL_STAKE_POOL_DEPOSIT_SOL_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: SplStakePoolDepositSolIxData.try_to_vec()?, }) } -pub fn spl_stake_pool_deposit_sol_invoke<'info>( - accounts: SplStakePoolDepositSolAccounts<'_, 'info>, +pub fn spl_stake_pool_deposit_sol_ix( + keys: SplStakePoolDepositSolKeys, +) -> std::io::Result { + spl_stake_pool_deposit_sol_ix_with_program_id(crate::ID, keys) +} +pub fn spl_stake_pool_deposit_sol_invoke_with_program_id( + program_id: Pubkey, + accounts: SplStakePoolDepositSolAccounts<'_, '_>, ) -> ProgramResult { - let ix = spl_stake_pool_deposit_sol_ix(accounts)?; - let account_info: [AccountInfo<'info>; SPL_STAKE_POOL_DEPOSIT_SOL_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + let keys: SplStakePoolDepositSolKeys = accounts.into(); + let ix = spl_stake_pool_deposit_sol_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn spl_stake_pool_deposit_sol_invoke( + accounts: SplStakePoolDepositSolAccounts<'_, '_>, +) -> ProgramResult { + spl_stake_pool_deposit_sol_invoke_with_program_id(crate::ID, accounts) +} +pub fn spl_stake_pool_deposit_sol_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: SplStakePoolDepositSolAccounts<'_, '_>, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let keys: SplStakePoolDepositSolKeys = accounts.into(); + let ix = spl_stake_pool_deposit_sol_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn spl_stake_pool_deposit_sol_invoke_signed<'info>( - accounts: SplStakePoolDepositSolAccounts<'_, 'info>, +pub fn spl_stake_pool_deposit_sol_invoke_signed( + accounts: SplStakePoolDepositSolAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = spl_stake_pool_deposit_sol_ix(accounts)?; - let account_info: [AccountInfo<'info>; SPL_STAKE_POOL_DEPOSIT_SOL_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + spl_stake_pool_deposit_sol_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn spl_stake_pool_deposit_sol_verify_account_keys( accounts: SplStakePoolDepositSolAccounts<'_, '_>, @@ -658,7 +731,7 @@ pub fn spl_stake_pool_deposit_sol_verify_account_keys( } Ok(()) } -pub fn spl_stake_pool_deposit_sol_verify_account_privileges<'me, 'info>( +pub fn spl_stake_pool_deposit_sol_verify_writable_privileges<'me, 'info>( accounts: SplStakePoolDepositSolAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -672,3 +745,9 @@ pub fn spl_stake_pool_deposit_sol_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn spl_stake_pool_deposit_sol_verify_account_privileges<'me, 'info>( + accounts: SplStakePoolDepositSolAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + spl_stake_pool_deposit_sol_verify_writable_privileges(accounts)?; + Ok(()) +} diff --git a/interfaces/stakedex_deposit_stake_interface/Cargo.toml b/interfaces/stakedex_deposit_stake_interface/Cargo.toml index 3a90d6b..b55d574 100644 --- a/interfaces/stakedex_deposit_stake_interface/Cargo.toml +++ b/interfaces/stakedex_deposit_stake_interface/Cargo.toml @@ -6,9 +6,9 @@ edition = "2021" [dependencies.borsh] workspace = true -[dependencies.solana-program] -workspace = true - [dependencies.serde] optional = true workspace = true + +[dependencies.solana-program] +workspace = true diff --git a/interfaces/stakedex_deposit_stake_interface/src/instructions.rs b/interfaces/stakedex_deposit_stake_interface/src/instructions.rs index 3ab00d1..2eff911 100644 --- a/interfaces/stakedex_deposit_stake_interface/src/instructions.rs +++ b/interfaces/stakedex_deposit_stake_interface/src/instructions.rs @@ -49,6 +49,21 @@ impl StakedexDepositStakeProgramIx { Ok(data) } } +fn invoke_instruction<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>( + ix: &Instruction, + accounts: A, +) -> ProgramResult { + let account_info: [AccountInfo<'info>; N] = accounts.into(); + invoke(ix, &account_info) +} +fn invoke_instruction_signed<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>( + ix: &Instruction, + accounts: A, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let account_info: [AccountInfo<'info>; N] = accounts.into(); + invoke_signed(ix, &account_info, seeds) +} pub const SOCEAN_STAKE_POOL_DEPOSIT_STAKE_IX_ACCOUNTS_LEN: usize = 12; #[derive(Copy, Clone, Debug)] pub struct SoceanStakePoolDepositStakeAccounts<'me, 'info> { @@ -257,33 +272,49 @@ impl SoceanStakePoolDepositStakeIxData { Ok(data) } } -pub fn socean_stake_pool_deposit_stake_ix>( - accounts: K, +pub fn socean_stake_pool_deposit_stake_ix_with_program_id( + program_id: Pubkey, + keys: SoceanStakePoolDepositStakeKeys, ) -> std::io::Result { - let keys: SoceanStakePoolDepositStakeKeys = accounts.into(); let metas: [AccountMeta; SOCEAN_STAKE_POOL_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: SoceanStakePoolDepositStakeIxData.try_to_vec()?, }) } -pub fn socean_stake_pool_deposit_stake_invoke<'info>( - accounts: SoceanStakePoolDepositStakeAccounts<'_, 'info>, +pub fn socean_stake_pool_deposit_stake_ix( + keys: SoceanStakePoolDepositStakeKeys, +) -> std::io::Result { + socean_stake_pool_deposit_stake_ix_with_program_id(crate::ID, keys) +} +pub fn socean_stake_pool_deposit_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: SoceanStakePoolDepositStakeAccounts<'_, '_>, ) -> ProgramResult { - let ix = socean_stake_pool_deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; SOCEAN_STAKE_POOL_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + let keys: SoceanStakePoolDepositStakeKeys = accounts.into(); + let ix = socean_stake_pool_deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) } -pub fn socean_stake_pool_deposit_stake_invoke_signed<'info>( - accounts: SoceanStakePoolDepositStakeAccounts<'_, 'info>, +pub fn socean_stake_pool_deposit_stake_invoke( + accounts: SoceanStakePoolDepositStakeAccounts<'_, '_>, +) -> ProgramResult { + socean_stake_pool_deposit_stake_invoke_with_program_id(crate::ID, accounts) +} +pub fn socean_stake_pool_deposit_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: SoceanStakePoolDepositStakeAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = socean_stake_pool_deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; SOCEAN_STAKE_POOL_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + let keys: SoceanStakePoolDepositStakeKeys = accounts.into(); + let ix = socean_stake_pool_deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) +} +pub fn socean_stake_pool_deposit_stake_invoke_signed( + accounts: SoceanStakePoolDepositStakeAccounts<'_, '_>, + seeds: &[&[&[u8]]], +) -> ProgramResult { + socean_stake_pool_deposit_stake_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn socean_stake_pool_deposit_stake_verify_account_keys( accounts: SoceanStakePoolDepositStakeAccounts<'_, '_>, @@ -333,7 +364,7 @@ pub fn socean_stake_pool_deposit_stake_verify_account_keys( } Ok(()) } -pub fn socean_stake_pool_deposit_stake_verify_account_privileges<'me, 'info>( +pub fn socean_stake_pool_deposit_stake_verify_writable_privileges<'me, 'info>( accounts: SoceanStakePoolDepositStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -349,6 +380,12 @@ pub fn socean_stake_pool_deposit_stake_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn socean_stake_pool_deposit_stake_verify_account_privileges<'me, 'info>( + accounts: SoceanStakePoolDepositStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + socean_stake_pool_deposit_stake_verify_writable_privileges(accounts)?; + Ok(()) +} pub const SPL_STAKE_POOL_DEPOSIT_STAKE_IX_ACCOUNTS_LEN: usize = 12; #[derive(Copy, Clone, Debug)] pub struct SplStakePoolDepositStakeAccounts<'me, 'info> { @@ -553,33 +590,49 @@ impl SplStakePoolDepositStakeIxData { Ok(data) } } -pub fn spl_stake_pool_deposit_stake_ix>( - accounts: K, +pub fn spl_stake_pool_deposit_stake_ix_with_program_id( + program_id: Pubkey, + keys: SplStakePoolDepositStakeKeys, ) -> std::io::Result { - let keys: SplStakePoolDepositStakeKeys = accounts.into(); let metas: [AccountMeta; SPL_STAKE_POOL_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: SplStakePoolDepositStakeIxData.try_to_vec()?, }) } -pub fn spl_stake_pool_deposit_stake_invoke<'info>( - accounts: SplStakePoolDepositStakeAccounts<'_, 'info>, +pub fn spl_stake_pool_deposit_stake_ix( + keys: SplStakePoolDepositStakeKeys, +) -> std::io::Result { + spl_stake_pool_deposit_stake_ix_with_program_id(crate::ID, keys) +} +pub fn spl_stake_pool_deposit_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: SplStakePoolDepositStakeAccounts<'_, '_>, ) -> ProgramResult { - let ix = spl_stake_pool_deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; SPL_STAKE_POOL_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + let keys: SplStakePoolDepositStakeKeys = accounts.into(); + let ix = spl_stake_pool_deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) } -pub fn spl_stake_pool_deposit_stake_invoke_signed<'info>( - accounts: SplStakePoolDepositStakeAccounts<'_, 'info>, +pub fn spl_stake_pool_deposit_stake_invoke( + accounts: SplStakePoolDepositStakeAccounts<'_, '_>, +) -> ProgramResult { + spl_stake_pool_deposit_stake_invoke_with_program_id(crate::ID, accounts) +} +pub fn spl_stake_pool_deposit_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: SplStakePoolDepositStakeAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = spl_stake_pool_deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; SPL_STAKE_POOL_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + let keys: SplStakePoolDepositStakeKeys = accounts.into(); + let ix = spl_stake_pool_deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) +} +pub fn spl_stake_pool_deposit_stake_invoke_signed( + accounts: SplStakePoolDepositStakeAccounts<'_, '_>, + seeds: &[&[&[u8]]], +) -> ProgramResult { + spl_stake_pool_deposit_stake_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn spl_stake_pool_deposit_stake_verify_account_keys( accounts: SplStakePoolDepositStakeAccounts<'_, '_>, @@ -629,7 +682,7 @@ pub fn spl_stake_pool_deposit_stake_verify_account_keys( } Ok(()) } -pub fn spl_stake_pool_deposit_stake_verify_account_privileges<'me, 'info>( +pub fn spl_stake_pool_deposit_stake_verify_writable_privileges<'me, 'info>( accounts: SplStakePoolDepositStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -645,6 +698,12 @@ pub fn spl_stake_pool_deposit_stake_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn spl_stake_pool_deposit_stake_verify_account_privileges<'me, 'info>( + accounts: SplStakePoolDepositStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + spl_stake_pool_deposit_stake_verify_writable_privileges(accounts)?; + Ok(()) +} pub const MARINADE_DEPOSIT_STAKE_IX_ACCOUNTS_LEN: usize = 11; #[derive(Copy, Clone, Debug)] pub struct MarinadeDepositStakeAccounts<'me, 'info> { @@ -836,33 +895,47 @@ impl MarinadeDepositStakeIxData { Ok(data) } } -pub fn marinade_deposit_stake_ix>( - accounts: K, +pub fn marinade_deposit_stake_ix_with_program_id( + program_id: Pubkey, + keys: MarinadeDepositStakeKeys, ) -> std::io::Result { - let keys: MarinadeDepositStakeKeys = accounts.into(); let metas: [AccountMeta; MARINADE_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: MarinadeDepositStakeIxData.try_to_vec()?, }) } -pub fn marinade_deposit_stake_invoke<'info>( - accounts: MarinadeDepositStakeAccounts<'_, 'info>, +pub fn marinade_deposit_stake_ix(keys: MarinadeDepositStakeKeys) -> std::io::Result { + marinade_deposit_stake_ix_with_program_id(crate::ID, keys) +} +pub fn marinade_deposit_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: MarinadeDepositStakeAccounts<'_, '_>, +) -> ProgramResult { + let keys: MarinadeDepositStakeKeys = accounts.into(); + let ix = marinade_deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn marinade_deposit_stake_invoke( + accounts: MarinadeDepositStakeAccounts<'_, '_>, ) -> ProgramResult { - let ix = marinade_deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; MARINADE_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + marinade_deposit_stake_invoke_with_program_id(crate::ID, accounts) } -pub fn marinade_deposit_stake_invoke_signed<'info>( - accounts: MarinadeDepositStakeAccounts<'_, 'info>, +pub fn marinade_deposit_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: MarinadeDepositStakeAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = marinade_deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; MARINADE_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + let keys: MarinadeDepositStakeKeys = accounts.into(); + let ix = marinade_deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) +} +pub fn marinade_deposit_stake_invoke_signed( + accounts: MarinadeDepositStakeAccounts<'_, '_>, + seeds: &[&[&[u8]]], +) -> ProgramResult { + marinade_deposit_stake_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn marinade_deposit_stake_verify_account_keys( accounts: MarinadeDepositStakeAccounts<'_, '_>, @@ -902,7 +975,7 @@ pub fn marinade_deposit_stake_verify_account_keys( } Ok(()) } -pub fn marinade_deposit_stake_verify_account_privileges<'me, 'info>( +pub fn marinade_deposit_stake_verify_writable_privileges<'me, 'info>( accounts: MarinadeDepositStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -917,6 +990,12 @@ pub fn marinade_deposit_stake_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn marinade_deposit_stake_verify_account_privileges<'me, 'info>( + accounts: MarinadeDepositStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + marinade_deposit_stake_verify_writable_privileges(accounts)?; + Ok(()) +} pub const UNSTAKE_IT_DEPOSIT_STAKE_IX_ACCOUNTS_LEN: usize = 11; #[derive(Copy, Clone, Debug)] pub struct UnstakeItDepositStakeAccounts<'me, 'info> { @@ -1108,33 +1187,49 @@ impl UnstakeItDepositStakeIxData { Ok(data) } } -pub fn unstake_it_deposit_stake_ix>( - accounts: K, +pub fn unstake_it_deposit_stake_ix_with_program_id( + program_id: Pubkey, + keys: UnstakeItDepositStakeKeys, ) -> std::io::Result { - let keys: UnstakeItDepositStakeKeys = accounts.into(); let metas: [AccountMeta; UNSTAKE_IT_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: UnstakeItDepositStakeIxData.try_to_vec()?, }) } -pub fn unstake_it_deposit_stake_invoke<'info>( - accounts: UnstakeItDepositStakeAccounts<'_, 'info>, +pub fn unstake_it_deposit_stake_ix( + keys: UnstakeItDepositStakeKeys, +) -> std::io::Result { + unstake_it_deposit_stake_ix_with_program_id(crate::ID, keys) +} +pub fn unstake_it_deposit_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: UnstakeItDepositStakeAccounts<'_, '_>, +) -> ProgramResult { + let keys: UnstakeItDepositStakeKeys = accounts.into(); + let ix = unstake_it_deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn unstake_it_deposit_stake_invoke( + accounts: UnstakeItDepositStakeAccounts<'_, '_>, +) -> ProgramResult { + unstake_it_deposit_stake_invoke_with_program_id(crate::ID, accounts) +} +pub fn unstake_it_deposit_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: UnstakeItDepositStakeAccounts<'_, '_>, + seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = unstake_it_deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; UNSTAKE_IT_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + let keys: UnstakeItDepositStakeKeys = accounts.into(); + let ix = unstake_it_deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn unstake_it_deposit_stake_invoke_signed<'info>( - accounts: UnstakeItDepositStakeAccounts<'_, 'info>, +pub fn unstake_it_deposit_stake_invoke_signed( + accounts: UnstakeItDepositStakeAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = unstake_it_deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; UNSTAKE_IT_DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + unstake_it_deposit_stake_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn unstake_it_deposit_stake_verify_account_keys( accounts: UnstakeItDepositStakeAccounts<'_, '_>, @@ -1177,7 +1272,7 @@ pub fn unstake_it_deposit_stake_verify_account_keys( } Ok(()) } -pub fn unstake_it_deposit_stake_verify_account_privileges<'me, 'info>( +pub fn unstake_it_deposit_stake_verify_writable_privileges<'me, 'info>( accounts: UnstakeItDepositStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -1192,3 +1287,9 @@ pub fn unstake_it_deposit_stake_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn unstake_it_deposit_stake_verify_account_privileges<'me, 'info>( + accounts: UnstakeItDepositStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + unstake_it_deposit_stake_verify_writable_privileges(accounts)?; + Ok(()) +} diff --git a/interfaces/stakedex_interface/Cargo.toml b/interfaces/stakedex_interface/Cargo.toml index be71c4b..92cc7a5 100644 --- a/interfaces/stakedex_interface/Cargo.toml +++ b/interfaces/stakedex_interface/Cargo.toml @@ -6,18 +6,18 @@ edition = "2021" [dependencies.borsh] workspace = true -[dependencies.solana-program] +[dependencies.num-derive] workspace = true -[dependencies.serde] -optional = true +[dependencies.num-traits] workspace = true -[dependencies.thiserror] +[dependencies.serde] +optional = true workspace = true -[dependencies.num-derive] +[dependencies.solana-program] workspace = true -[dependencies.num-traits] +[dependencies.thiserror] workspace = true diff --git a/interfaces/stakedex_interface/idl.json b/interfaces/stakedex_interface/idl.json index c49df8d..572b0f0 100644 --- a/interfaces/stakedex_interface/idl.json +++ b/interfaces/stakedex_interface/idl.json @@ -61,7 +61,8 @@ { "name": "systemProgram", "isMut": false, - "isSigner": false + "isSigner": false, + "desc": "System program. The deposit SOL accounts slice follows." } ], "args": [ @@ -82,7 +83,7 @@ "name": "user", "isMut": true, "isSigner": true, - "desc": "The authority of src_token_from. Needs to be mutable to support marinde deposit stake." + "desc": "The authority of src_token_from. Needs to be mutable to support marinade deposit stake." }, { "name": "srcTokenFrom", @@ -118,17 +119,15 @@ "name": "destTokenMint", "isMut": true, "isSigner": false, - "desc": "Output token mint. If this is wrapped SOL, the account can be set to read-only" + "desc": "Output token mint. If this is wrapped SOL, the account can be set to read-only. The withdraw stake and deposit stake accounts slices follow." } ], "args": [ { - "name": "amount", - "type": "u64" - }, - { - "name": "bridgeStakeSeed", - "type": "u32" + "name": "args", + "type": { + "defined": "SwapViaStakeArgs" + } } ], "discriminant": { @@ -280,7 +279,7 @@ "name": "destTokenMint", "isMut": true, "isSigner": false, - "desc": "Output token mint. If this is wrapped SOL, the account can be set to read-only" + "desc": "Output token mint. If this is wrapped SOL, the account can be set to read-only. The deposit stake accounts slice follows." } ], "args": [], @@ -288,6 +287,268 @@ "type": "u8", "value": 5 } + }, + { + "name": "PrefundWithdrawStake", + "accounts": [ + { + "name": "user", + "isMut": true, + "isSigner": true, + "desc": "The withdraw authority of stake_account. Needs to be mutable and system account to receive slumlord flash loan." + }, + { + "name": "srcTokenFrom", + "isMut": true, + "isSigner": false, + "desc": "The token account to burn src tokens from in order to withdraw stake" + }, + { + "name": "bridgeStake", + "isMut": true, + "isSigner": false, + "desc": "The bridge stake account thats withdrawn and given to the user. PDA. seeds = ['bridge_stake', user.pubkey, SwapArgs.bridge_stake_seed]. Might be long-lived, make sure the seed is not already in use" + }, + { + "name": "srcTokenMint", + "isMut": true, + "isSigner": false, + "desc": "Input LST token mint" + }, + { + "name": "prefunder", + "isMut": true, + "isSigner": false, + "desc": "The system account PDA that contains enough SOL to prefund 2 stake accounts for withdrawal. Someone must send SOL to here to initialize it. Seeds = ['prefunder']" + }, + { + "name": "slumdogStake", + "isMut": true, + "isSigner": false, + "desc": "The slumdog stake account is split from bridge_stake upon stake withdraw and instant unstaked to repay slumlord's flash loan. create_with_seed(bridge_stake.pubkey, 'slumdog', stake_program). Might be long-lived, but should be not in use as long as bridge_stake is not in use" + }, + { + "name": "unstakeitProgram", + "isMut": false, + "isSigner": false, + "desc": "Sanctum unstake program. unpXTU2Ndrc7WWNyEhQWe4udTzSibLPi25SXv2xbCHQ" + }, + { + "name": "unstakePool", + "isMut": true, + "isSigner": false, + "desc": "Sanctum unstake pool. FypPtwbY3FUfzJUtXHSyVRokVKG2jKtH29FmK4ebxRSd" + }, + { + "name": "poolSolReserves", + "isMut": true, + "isSigner": false, + "desc": "Sanctum unstake pool SOL reserves. 3rBnnH9TTgd3xwu48rnzGsaQkSr1hR64nY71DrDt6VrQ" + }, + { + "name": "unstakeFee", + "isMut": false, + "isSigner": false, + "desc": "Sanctum unstake pool Fee account. 5Pcu8WeQa3VbBz2vdBT49Rj4gbS4hsnfzuL1LmuRaKFY" + }, + { + "name": "slumdogStakeAccRecord", + "isMut": true, + "isSigner": false, + "desc": "Sanctum unstake pool stake account record for slumdog stake. PDA of sanctum unstake program. Seeds = [unstakePool.pubkey, slumdogStake.pubkey]." + }, + { + "name": "unstakeProtocolFee", + "isMut": false, + "isSigner": false, + "desc": "Sanctum unstake pool protocol fee account. 2hN9UhvRFVfPYKL6rZJ5YiLEPCLTpN755pgwDJHWgFbU" + }, + { + "name": "unstakeProtocolFeeDest", + "isMut": true, + "isSigner": false, + "desc": "Sanctum unstake pool protocol fee destination. unstakeProtocolFee.destination" + }, + { + "name": "clock", + "isMut": false, + "isSigner": false, + "desc": "sysvar clock" + }, + { + "name": "stakeProgram", + "isMut": false, + "isSigner": false, + "desc": "stake program" + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false, + "desc": "System program. The withdraw stake accounts slices follow." + } + ], + "args": [ + { + "name": "args", + "type": { + "defined": "SwapViaStakeArgs" + } + } + ], + "discriminant": { + "type": "u8", + "value": 6 + } + }, + { + "name": "PrefundSwapViaStake", + "accounts": [ + { + "name": "user", + "isMut": true, + "isSigner": true, + "desc": "The authority of src_token_from, mutable system account. Prefunds the rent for the stake accounts, amount is refunded via instant unstake." + }, + { + "name": "srcTokenFrom", + "isMut": true, + "isSigner": false, + "desc": "The token account to swap src tokens from" + }, + { + "name": "destTokenTo", + "isMut": true, + "isSigner": false, + "desc": "The token account to receive dest tokens to" + }, + { + "name": "bridgeStake", + "isMut": true, + "isSigner": false, + "desc": "The bridge stake account thats withdrawn then deposited. PDA. seeds = ['bridge_stake', user.pubkey, SwapArgs.bridge_stake_seed]. Might be long-lived, make sure the seed is not already in use" + }, + { + "name": "destTokenFeeTokenAccount", + "isMut": true, + "isSigner": false, + "desc": "The dest_token_mint token account collecting fees. PDA. Seeds = ['fee', dest_token_mint.pubkey]" + }, + { + "name": "srcTokenMint", + "isMut": true, + "isSigner": false, + "desc": "Input token mint. If this is wrapped SOL, the account can be set to read-only" + }, + { + "name": "destTokenMint", + "isMut": true, + "isSigner": false, + "desc": "Output token mint. If this is wrapped SOL, the account can be set to read-only" + }, + { + "name": "prefunder", + "isMut": true, + "isSigner": false, + "desc": "The system account PDA that contains enough SOL to prefund 2 stake accounts for withdrawal. Someone must send SOL to here to initialize it. Seeds = ['prefunder']" + }, + { + "name": "slumdogStake", + "isMut": true, + "isSigner": false, + "desc": "The slumdog stake account is split from bridge_stake upon stake withdraw and instant unstaked to refund user. create_with_seed(bridge_stake.pubkey, 'slumdog', stake_program). Might be long-lived, but should be not in use as long as bridge_stake is not in use" + }, + { + "name": "unstakeitProgram", + "isMut": false, + "isSigner": false, + "desc": "Sanctum unstake program. unpXTU2Ndrc7WWNyEhQWe4udTzSibLPi25SXv2xbCHQ" + }, + { + "name": "unstakePool", + "isMut": true, + "isSigner": false, + "desc": "Sanctum unstake pool. FypPtwbY3FUfzJUtXHSyVRokVKG2jKtH29FmK4ebxRSd" + }, + { + "name": "poolSolReserves", + "isMut": true, + "isSigner": false, + "desc": "Sanctum unstake pool SOL reserves. 3rBnnH9TTgd3xwu48rnzGsaQkSr1hR64nY71DrDt6VrQ" + }, + { + "name": "unstakeFee", + "isMut": false, + "isSigner": false, + "desc": "Sanctum unstake pool Fee account. 5Pcu8WeQa3VbBz2vdBT49Rj4gbS4hsnfzuL1LmuRaKFY" + }, + { + "name": "slumdogStakeAccRecord", + "isMut": true, + "isSigner": false, + "desc": "Sanctum unstake pool stake account record for slumdog stake. PDA of sanctum unstake program. Seeds = [unstakePool.pubkey, slumdogStake.pubkey]." + }, + { + "name": "unstakeProtocolFee", + "isMut": false, + "isSigner": false, + "desc": "Sanctum unstake pool protocol fee account. 2hN9UhvRFVfPYKL6rZJ5YiLEPCLTpN755pgwDJHWgFbU" + }, + { + "name": "unstakeProtocolFeeDest", + "isMut": true, + "isSigner": false, + "desc": "Sanctum unstake pool protocol fee destination. unstakeProtocolFee.destination" + }, + { + "name": "clock", + "isMut": false, + "isSigner": false, + "desc": "sysvar clock" + }, + { + "name": "stakeProgram", + "isMut": false, + "isSigner": false, + "desc": "stake program" + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false, + "desc": "System program. The withdraw stake and deposit stake accounts slices follow." + } + ], + "args": [ + { + "name": "args", + "type": { + "defined": "SwapViaStakeArgs" + } + } + ], + "discriminant": { + "type": "u8", + "value": 7 + } + } + ], + "types": [ + { + "name": "SwapViaStakeArgs", + "type": { + "kind": "struct", + "fields": [ + { + "name": "amount", + "type": "u64" + }, + { + "name": "bridgeStakeSeed", + "type": "u32" + } + ] + } } ], "errors": [ @@ -365,6 +626,11 @@ "code": 14, "name": "UnreachableError", "msg": "If you see this, there's a serious bug somewhere" + }, + { + "code": 17, + "name": "SlumdogUnstakeTooSmall", + "msg": "Instant unstake of slumdog stake was not enough to cover rent" } ], "metadata": { diff --git a/interfaces/stakedex_interface/src/errors.rs b/interfaces/stakedex_interface/src/errors.rs index 6898f14..b2e08bb 100644 --- a/interfaces/stakedex_interface/src/errors.rs +++ b/interfaces/stakedex_interface/src/errors.rs @@ -36,6 +36,8 @@ pub enum StakedexError { UnsupportedProgram = 13, #[error("If you see this, there's a serious bug somewhere")] UnreachableError = 14, + #[error("Instant unstake of slumdog stake was not enough to cover rent")] + SlumdogUnstakeTooSmall = 17, } impl From for ProgramError { fn from(e: StakedexError) -> Self { diff --git a/interfaces/stakedex_interface/src/instructions.rs b/interfaces/stakedex_interface/src/instructions.rs index 60e806a..a901d73 100644 --- a/interfaces/stakedex_interface/src/instructions.rs +++ b/interfaces/stakedex_interface/src/instructions.rs @@ -1,3 +1,4 @@ +use crate::*; use borsh::{BorshDeserialize, BorshSerialize}; use solana_program::{ account_info::AccountInfo, @@ -16,6 +17,8 @@ pub enum StakedexProgramIx { CloseFeeTokenAccount, WithdrawFees, DepositStake, + PrefundWithdrawStake(PrefundWithdrawStakeIxArgs), + PrefundSwapViaStake(PrefundSwapViaStakeIxArgs), } impl StakedexProgramIx { pub fn deserialize(buf: &[u8]) -> std::io::Result { @@ -34,6 +37,12 @@ impl StakedexProgramIx { CLOSE_FEE_TOKEN_ACCOUNT_IX_DISCM => Ok(Self::CloseFeeTokenAccount), WITHDRAW_FEES_IX_DISCM => Ok(Self::WithdrawFees), DEPOSIT_STAKE_IX_DISCM => Ok(Self::DepositStake), + PREFUND_WITHDRAW_STAKE_IX_DISCM => Ok(Self::PrefundWithdrawStake( + PrefundWithdrawStakeIxArgs::deserialize(&mut reader)?, + )), + PREFUND_SWAP_VIA_STAKE_IX_DISCM => Ok(Self::PrefundSwapViaStake( + PrefundSwapViaStakeIxArgs::deserialize(&mut reader)?, + )), _ => Err(std::io::Error::new( std::io::ErrorKind::Other, format!("discm {:?} not found", maybe_discm), @@ -54,6 +63,14 @@ impl StakedexProgramIx { Self::CloseFeeTokenAccount => writer.write_all(&[CLOSE_FEE_TOKEN_ACCOUNT_IX_DISCM]), Self::WithdrawFees => writer.write_all(&[WITHDRAW_FEES_IX_DISCM]), Self::DepositStake => writer.write_all(&[DEPOSIT_STAKE_IX_DISCM]), + Self::PrefundWithdrawStake(args) => { + writer.write_all(&[PREFUND_WITHDRAW_STAKE_IX_DISCM])?; + args.serialize(&mut writer) + } + Self::PrefundSwapViaStake(args) => { + writer.write_all(&[PREFUND_SWAP_VIA_STAKE_IX_DISCM])?; + args.serialize(&mut writer) + } } } pub fn try_to_vec(&self) -> std::io::Result> { @@ -62,6 +79,21 @@ impl StakedexProgramIx { Ok(data) } } +fn invoke_instruction<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>( + ix: &Instruction, + accounts: A, +) -> ProgramResult { + let account_info: [AccountInfo<'info>; N] = accounts.into(); + invoke(ix, &account_info) +} +fn invoke_instruction_signed<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>( + ix: &Instruction, + accounts: A, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let account_info: [AccountInfo<'info>; N] = accounts.into(); + invoke_signed(ix, &account_info, seeds) +} pub const STAKE_WRAPPED_SOL_IX_ACCOUNTS_LEN: usize = 10; #[derive(Copy, Clone, Debug)] pub struct StakeWrappedSolAccounts<'me, 'info> { @@ -82,6 +114,7 @@ pub struct StakeWrappedSolAccounts<'me, 'info> { ///wSOL token mint pub wsol_mint: &'me AccountInfo<'info>, pub token_program: &'me AccountInfo<'info>, + ///System program. The deposit SOL accounts slice follows. pub system_program: &'me AccountInfo<'info>, } #[derive(Copy, Clone, Debug)] @@ -103,6 +136,7 @@ pub struct StakeWrappedSolKeys { ///wSOL token mint pub wsol_mint: Pubkey, pub token_program: Pubkey, + ///System program. The deposit SOL accounts slice follows. pub system_program: Pubkey, } impl From> for StakeWrappedSolKeys { @@ -269,36 +303,56 @@ impl StakeWrappedSolIxData { Ok(data) } } -pub fn stake_wrapped_sol_ix, A: Into>( - accounts: K, - args: A, +pub fn stake_wrapped_sol_ix_with_program_id( + program_id: Pubkey, + keys: StakeWrappedSolKeys, + args: StakeWrappedSolIxArgs, ) -> std::io::Result { - let keys: StakeWrappedSolKeys = accounts.into(); let metas: [AccountMeta; STAKE_WRAPPED_SOL_IX_ACCOUNTS_LEN] = keys.into(); - let args_full: StakeWrappedSolIxArgs = args.into(); - let data: StakeWrappedSolIxData = args_full.into(); + let data: StakeWrappedSolIxData = args.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: data.try_to_vec()?, }) } -pub fn stake_wrapped_sol_invoke<'info, A: Into>( - accounts: StakeWrappedSolAccounts<'_, 'info>, - args: A, +pub fn stake_wrapped_sol_ix( + keys: StakeWrappedSolKeys, + args: StakeWrappedSolIxArgs, +) -> std::io::Result { + stake_wrapped_sol_ix_with_program_id(crate::ID, keys, args) +} +pub fn stake_wrapped_sol_invoke_with_program_id( + program_id: Pubkey, + accounts: StakeWrappedSolAccounts<'_, '_>, + args: StakeWrappedSolIxArgs, +) -> ProgramResult { + let keys: StakeWrappedSolKeys = accounts.into(); + let ix = stake_wrapped_sol_ix_with_program_id(program_id, keys, args)?; + invoke_instruction(&ix, accounts) +} +pub fn stake_wrapped_sol_invoke( + accounts: StakeWrappedSolAccounts<'_, '_>, + args: StakeWrappedSolIxArgs, +) -> ProgramResult { + stake_wrapped_sol_invoke_with_program_id(crate::ID, accounts, args) +} +pub fn stake_wrapped_sol_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: StakeWrappedSolAccounts<'_, '_>, + args: StakeWrappedSolIxArgs, + seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = stake_wrapped_sol_ix(accounts, args)?; - let account_info: [AccountInfo<'info>; STAKE_WRAPPED_SOL_IX_ACCOUNTS_LEN] = accounts.into(); - invoke(&ix, &account_info) + let keys: StakeWrappedSolKeys = accounts.into(); + let ix = stake_wrapped_sol_ix_with_program_id(program_id, keys, args)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn stake_wrapped_sol_invoke_signed<'info, A: Into>( - accounts: StakeWrappedSolAccounts<'_, 'info>, - args: A, +pub fn stake_wrapped_sol_invoke_signed( + accounts: StakeWrappedSolAccounts<'_, '_>, + args: StakeWrappedSolIxArgs, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = stake_wrapped_sol_ix(accounts, args)?; - let account_info: [AccountInfo<'info>; STAKE_WRAPPED_SOL_IX_ACCOUNTS_LEN] = accounts.into(); - invoke_signed(&ix, &account_info, seeds) + stake_wrapped_sol_invoke_signed_with_program_id(crate::ID, accounts, args, seeds) } pub fn stake_wrapped_sol_verify_account_keys( accounts: StakeWrappedSolAccounts<'_, '_>, @@ -325,7 +379,7 @@ pub fn stake_wrapped_sol_verify_account_keys( } Ok(()) } -pub fn stake_wrapped_sol_verify_account_privileges<'me, 'info>( +pub fn stake_wrapped_sol_verify_writable_privileges<'me, 'info>( accounts: StakeWrappedSolAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -340,6 +394,11 @@ pub fn stake_wrapped_sol_verify_account_privileges<'me, 'info>( return Err((should_be_writable, ProgramError::InvalidAccountData)); } } + Ok(()) +} +pub fn stake_wrapped_sol_verify_signer_privileges<'me, 'info>( + accounts: StakeWrappedSolAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_signer in [accounts.user] { if !should_be_signer.is_signer { return Err((should_be_signer, ProgramError::MissingRequiredSignature)); @@ -347,10 +406,17 @@ pub fn stake_wrapped_sol_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn stake_wrapped_sol_verify_account_privileges<'me, 'info>( + accounts: StakeWrappedSolAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + stake_wrapped_sol_verify_writable_privileges(accounts)?; + stake_wrapped_sol_verify_signer_privileges(accounts)?; + Ok(()) +} pub const SWAP_VIA_STAKE_IX_ACCOUNTS_LEN: usize = 7; #[derive(Copy, Clone, Debug)] pub struct SwapViaStakeAccounts<'me, 'info> { - ///The authority of src_token_from. Needs to be mutable to support marinde deposit stake. + ///The authority of src_token_from. Needs to be mutable to support marinade deposit stake. pub user: &'me AccountInfo<'info>, ///The token account to swap src tokens from pub src_token_from: &'me AccountInfo<'info>, @@ -362,12 +428,12 @@ pub struct SwapViaStakeAccounts<'me, 'info> { pub dest_token_fee_token_account: &'me AccountInfo<'info>, ///Input token mint. If this is wrapped SOL, the account can be set to read-only pub src_token_mint: &'me AccountInfo<'info>, - ///Output token mint. If this is wrapped SOL, the account can be set to read-only + ///Output token mint. If this is wrapped SOL, the account can be set to read-only. The withdraw stake and deposit stake accounts slices follow. pub dest_token_mint: &'me AccountInfo<'info>, } #[derive(Copy, Clone, Debug)] pub struct SwapViaStakeKeys { - ///The authority of src_token_from. Needs to be mutable to support marinde deposit stake. + ///The authority of src_token_from. Needs to be mutable to support marinade deposit stake. pub user: Pubkey, ///The token account to swap src tokens from pub src_token_from: Pubkey, @@ -379,7 +445,7 @@ pub struct SwapViaStakeKeys { pub dest_token_fee_token_account: Pubkey, ///Input token mint. If this is wrapped SOL, the account can be set to read-only pub src_token_mint: Pubkey, - ///Output token mint. If this is wrapped SOL, the account can be set to read-only + ///Output token mint. If this is wrapped SOL, the account can be set to read-only. The withdraw stake and deposit stake accounts slices follow. pub dest_token_mint: Pubkey, } impl From> for SwapViaStakeKeys { @@ -483,8 +549,7 @@ pub const SWAP_VIA_STAKE_IX_DISCM: u8 = 1u8; #[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SwapViaStakeIxArgs { - pub amount: u64, - pub bridge_stake_seed: u32, + pub args: SwapViaStakeArgs, } #[derive(Clone, Debug, PartialEq)] pub struct SwapViaStakeIxData(pub SwapViaStakeIxArgs); @@ -520,36 +585,56 @@ impl SwapViaStakeIxData { Ok(data) } } -pub fn swap_via_stake_ix, A: Into>( - accounts: K, - args: A, +pub fn swap_via_stake_ix_with_program_id( + program_id: Pubkey, + keys: SwapViaStakeKeys, + args: SwapViaStakeIxArgs, ) -> std::io::Result { - let keys: SwapViaStakeKeys = accounts.into(); let metas: [AccountMeta; SWAP_VIA_STAKE_IX_ACCOUNTS_LEN] = keys.into(); - let args_full: SwapViaStakeIxArgs = args.into(); - let data: SwapViaStakeIxData = args_full.into(); + let data: SwapViaStakeIxData = args.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: data.try_to_vec()?, }) } -pub fn swap_via_stake_invoke<'info, A: Into>( - accounts: SwapViaStakeAccounts<'_, 'info>, - args: A, +pub fn swap_via_stake_ix( + keys: SwapViaStakeKeys, + args: SwapViaStakeIxArgs, +) -> std::io::Result { + swap_via_stake_ix_with_program_id(crate::ID, keys, args) +} +pub fn swap_via_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: SwapViaStakeAccounts<'_, '_>, + args: SwapViaStakeIxArgs, +) -> ProgramResult { + let keys: SwapViaStakeKeys = accounts.into(); + let ix = swap_via_stake_ix_with_program_id(program_id, keys, args)?; + invoke_instruction(&ix, accounts) +} +pub fn swap_via_stake_invoke( + accounts: SwapViaStakeAccounts<'_, '_>, + args: SwapViaStakeIxArgs, +) -> ProgramResult { + swap_via_stake_invoke_with_program_id(crate::ID, accounts, args) +} +pub fn swap_via_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: SwapViaStakeAccounts<'_, '_>, + args: SwapViaStakeIxArgs, + seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = swap_via_stake_ix(accounts, args)?; - let account_info: [AccountInfo<'info>; SWAP_VIA_STAKE_IX_ACCOUNTS_LEN] = accounts.into(); - invoke(&ix, &account_info) + let keys: SwapViaStakeKeys = accounts.into(); + let ix = swap_via_stake_ix_with_program_id(program_id, keys, args)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn swap_via_stake_invoke_signed<'info, A: Into>( - accounts: SwapViaStakeAccounts<'_, 'info>, - args: A, +pub fn swap_via_stake_invoke_signed( + accounts: SwapViaStakeAccounts<'_, '_>, + args: SwapViaStakeIxArgs, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = swap_via_stake_ix(accounts, args)?; - let account_info: [AccountInfo<'info>; SWAP_VIA_STAKE_IX_ACCOUNTS_LEN] = accounts.into(); - invoke_signed(&ix, &account_info, seeds) + swap_via_stake_invoke_signed_with_program_id(crate::ID, accounts, args, seeds) } pub fn swap_via_stake_verify_account_keys( accounts: SwapViaStakeAccounts<'_, '_>, @@ -573,7 +658,7 @@ pub fn swap_via_stake_verify_account_keys( } Ok(()) } -pub fn swap_via_stake_verify_account_privileges<'me, 'info>( +pub fn swap_via_stake_verify_writable_privileges<'me, 'info>( accounts: SwapViaStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -589,6 +674,11 @@ pub fn swap_via_stake_verify_account_privileges<'me, 'info>( return Err((should_be_writable, ProgramError::InvalidAccountData)); } } + Ok(()) +} +pub fn swap_via_stake_verify_signer_privileges<'me, 'info>( + accounts: SwapViaStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_signer in [accounts.user] { if !should_be_signer.is_signer { return Err((should_be_signer, ProgramError::MissingRequiredSignature)); @@ -596,6 +686,13 @@ pub fn swap_via_stake_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn swap_via_stake_verify_account_privileges<'me, 'info>( + accounts: SwapViaStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + swap_via_stake_verify_writable_privileges(accounts)?; + swap_via_stake_verify_signer_privileges(accounts)?; + Ok(()) +} pub const CREATE_FEE_TOKEN_ACCOUNT_IX_ACCOUNTS_LEN: usize = 5; #[derive(Copy, Clone, Debug)] pub struct CreateFeeTokenAccountAccounts<'me, 'info> { @@ -725,33 +822,49 @@ impl CreateFeeTokenAccountIxData { Ok(data) } } -pub fn create_fee_token_account_ix>( - accounts: K, +pub fn create_fee_token_account_ix_with_program_id( + program_id: Pubkey, + keys: CreateFeeTokenAccountKeys, ) -> std::io::Result { - let keys: CreateFeeTokenAccountKeys = accounts.into(); let metas: [AccountMeta; CREATE_FEE_TOKEN_ACCOUNT_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: CreateFeeTokenAccountIxData.try_to_vec()?, }) } -pub fn create_fee_token_account_invoke<'info>( - accounts: CreateFeeTokenAccountAccounts<'_, 'info>, +pub fn create_fee_token_account_ix( + keys: CreateFeeTokenAccountKeys, +) -> std::io::Result { + create_fee_token_account_ix_with_program_id(crate::ID, keys) +} +pub fn create_fee_token_account_invoke_with_program_id( + program_id: Pubkey, + accounts: CreateFeeTokenAccountAccounts<'_, '_>, +) -> ProgramResult { + let keys: CreateFeeTokenAccountKeys = accounts.into(); + let ix = create_fee_token_account_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn create_fee_token_account_invoke( + accounts: CreateFeeTokenAccountAccounts<'_, '_>, +) -> ProgramResult { + create_fee_token_account_invoke_with_program_id(crate::ID, accounts) +} +pub fn create_fee_token_account_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: CreateFeeTokenAccountAccounts<'_, '_>, + seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = create_fee_token_account_ix(accounts)?; - let account_info: [AccountInfo<'info>; CREATE_FEE_TOKEN_ACCOUNT_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + let keys: CreateFeeTokenAccountKeys = accounts.into(); + let ix = create_fee_token_account_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn create_fee_token_account_invoke_signed<'info>( - accounts: CreateFeeTokenAccountAccounts<'_, 'info>, +pub fn create_fee_token_account_invoke_signed( + accounts: CreateFeeTokenAccountAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = create_fee_token_account_ix(accounts)?; - let account_info: [AccountInfo<'info>; CREATE_FEE_TOKEN_ACCOUNT_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + create_fee_token_account_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn create_fee_token_account_verify_account_keys( accounts: CreateFeeTokenAccountAccounts<'_, '_>, @@ -770,7 +883,7 @@ pub fn create_fee_token_account_verify_account_keys( } Ok(()) } -pub fn create_fee_token_account_verify_account_privileges<'me, 'info>( +pub fn create_fee_token_account_verify_writable_privileges<'me, 'info>( accounts: CreateFeeTokenAccountAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [accounts.payer, accounts.fee_token_account] { @@ -778,6 +891,11 @@ pub fn create_fee_token_account_verify_account_privileges<'me, 'info>( return Err((should_be_writable, ProgramError::InvalidAccountData)); } } + Ok(()) +} +pub fn create_fee_token_account_verify_signer_privileges<'me, 'info>( + accounts: CreateFeeTokenAccountAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_signer in [accounts.payer] { if !should_be_signer.is_signer { return Err((should_be_signer, ProgramError::MissingRequiredSignature)); @@ -785,6 +903,13 @@ pub fn create_fee_token_account_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn create_fee_token_account_verify_account_privileges<'me, 'info>( + accounts: CreateFeeTokenAccountAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + create_fee_token_account_verify_writable_privileges(accounts)?; + create_fee_token_account_verify_signer_privileges(accounts)?; + Ok(()) +} pub const CLOSE_FEE_TOKEN_ACCOUNT_IX_ACCOUNTS_LEN: usize = 5; #[derive(Copy, Clone, Debug)] pub struct CloseFeeTokenAccountAccounts<'me, 'info> { @@ -916,33 +1041,47 @@ impl CloseFeeTokenAccountIxData { Ok(data) } } -pub fn close_fee_token_account_ix>( - accounts: K, +pub fn close_fee_token_account_ix_with_program_id( + program_id: Pubkey, + keys: CloseFeeTokenAccountKeys, ) -> std::io::Result { - let keys: CloseFeeTokenAccountKeys = accounts.into(); let metas: [AccountMeta; CLOSE_FEE_TOKEN_ACCOUNT_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: CloseFeeTokenAccountIxData.try_to_vec()?, }) } -pub fn close_fee_token_account_invoke<'info>( - accounts: CloseFeeTokenAccountAccounts<'_, 'info>, +pub fn close_fee_token_account_ix(keys: CloseFeeTokenAccountKeys) -> std::io::Result { + close_fee_token_account_ix_with_program_id(crate::ID, keys) +} +pub fn close_fee_token_account_invoke_with_program_id( + program_id: Pubkey, + accounts: CloseFeeTokenAccountAccounts<'_, '_>, +) -> ProgramResult { + let keys: CloseFeeTokenAccountKeys = accounts.into(); + let ix = close_fee_token_account_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn close_fee_token_account_invoke( + accounts: CloseFeeTokenAccountAccounts<'_, '_>, +) -> ProgramResult { + close_fee_token_account_invoke_with_program_id(crate::ID, accounts) +} +pub fn close_fee_token_account_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: CloseFeeTokenAccountAccounts<'_, '_>, + seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = close_fee_token_account_ix(accounts)?; - let account_info: [AccountInfo<'info>; CLOSE_FEE_TOKEN_ACCOUNT_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + let keys: CloseFeeTokenAccountKeys = accounts.into(); + let ix = close_fee_token_account_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn close_fee_token_account_invoke_signed<'info>( - accounts: CloseFeeTokenAccountAccounts<'_, 'info>, +pub fn close_fee_token_account_invoke_signed( + accounts: CloseFeeTokenAccountAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = close_fee_token_account_ix(accounts)?; - let account_info: [AccountInfo<'info>; CLOSE_FEE_TOKEN_ACCOUNT_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + close_fee_token_account_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn close_fee_token_account_verify_account_keys( accounts: CloseFeeTokenAccountAccounts<'_, '_>, @@ -961,7 +1100,7 @@ pub fn close_fee_token_account_verify_account_keys( } Ok(()) } -pub fn close_fee_token_account_verify_account_privileges<'me, 'info>( +pub fn close_fee_token_account_verify_writable_privileges<'me, 'info>( accounts: CloseFeeTokenAccountAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [accounts.fee_token_account, accounts.close_to] { @@ -969,6 +1108,11 @@ pub fn close_fee_token_account_verify_account_privileges<'me, 'info>( return Err((should_be_writable, ProgramError::InvalidAccountData)); } } + Ok(()) +} +pub fn close_fee_token_account_verify_signer_privileges<'me, 'info>( + accounts: CloseFeeTokenAccountAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_signer in [accounts.admin] { if !should_be_signer.is_signer { return Err((should_be_signer, ProgramError::MissingRequiredSignature)); @@ -976,6 +1120,13 @@ pub fn close_fee_token_account_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn close_fee_token_account_verify_account_privileges<'me, 'info>( + accounts: CloseFeeTokenAccountAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + close_fee_token_account_verify_writable_privileges(accounts)?; + close_fee_token_account_verify_signer_privileges(accounts)?; + Ok(()) +} pub const WITHDRAW_FEES_IX_ACCOUNTS_LEN: usize = 5; #[derive(Copy, Clone, Debug)] pub struct WithdrawFeesAccounts<'me, 'info> { @@ -1107,27 +1258,45 @@ impl WithdrawFeesIxData { Ok(data) } } -pub fn withdraw_fees_ix>(accounts: K) -> std::io::Result { - let keys: WithdrawFeesKeys = accounts.into(); +pub fn withdraw_fees_ix_with_program_id( + program_id: Pubkey, + keys: WithdrawFeesKeys, +) -> std::io::Result { let metas: [AccountMeta; WITHDRAW_FEES_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: WithdrawFeesIxData.try_to_vec()?, }) } -pub fn withdraw_fees_invoke<'info>(accounts: WithdrawFeesAccounts<'_, 'info>) -> ProgramResult { - let ix = withdraw_fees_ix(accounts)?; - let account_info: [AccountInfo<'info>; WITHDRAW_FEES_IX_ACCOUNTS_LEN] = accounts.into(); - invoke(&ix, &account_info) +pub fn withdraw_fees_ix(keys: WithdrawFeesKeys) -> std::io::Result { + withdraw_fees_ix_with_program_id(crate::ID, keys) +} +pub fn withdraw_fees_invoke_with_program_id( + program_id: Pubkey, + accounts: WithdrawFeesAccounts<'_, '_>, +) -> ProgramResult { + let keys: WithdrawFeesKeys = accounts.into(); + let ix = withdraw_fees_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn withdraw_fees_invoke(accounts: WithdrawFeesAccounts<'_, '_>) -> ProgramResult { + withdraw_fees_invoke_with_program_id(crate::ID, accounts) +} +pub fn withdraw_fees_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: WithdrawFeesAccounts<'_, '_>, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let keys: WithdrawFeesKeys = accounts.into(); + let ix = withdraw_fees_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn withdraw_fees_invoke_signed<'info>( - accounts: WithdrawFeesAccounts<'_, 'info>, +pub fn withdraw_fees_invoke_signed( + accounts: WithdrawFeesAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = withdraw_fees_ix(accounts)?; - let account_info: [AccountInfo<'info>; WITHDRAW_FEES_IX_ACCOUNTS_LEN] = accounts.into(); - invoke_signed(&ix, &account_info, seeds) + withdraw_fees_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn withdraw_fees_verify_account_keys( accounts: WithdrawFeesAccounts<'_, '_>, @@ -1146,7 +1315,7 @@ pub fn withdraw_fees_verify_account_keys( } Ok(()) } -pub fn withdraw_fees_verify_account_privileges<'me, 'info>( +pub fn withdraw_fees_verify_writable_privileges<'me, 'info>( accounts: WithdrawFeesAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [accounts.fee_token_account, accounts.withdraw_to] { @@ -1154,6 +1323,11 @@ pub fn withdraw_fees_verify_account_privileges<'me, 'info>( return Err((should_be_writable, ProgramError::InvalidAccountData)); } } + Ok(()) +} +pub fn withdraw_fees_verify_signer_privileges<'me, 'info>( + accounts: WithdrawFeesAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_signer in [accounts.admin] { if !should_be_signer.is_signer { return Err((should_be_signer, ProgramError::MissingRequiredSignature)); @@ -1161,6 +1335,13 @@ pub fn withdraw_fees_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn withdraw_fees_verify_account_privileges<'me, 'info>( + accounts: WithdrawFeesAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + withdraw_fees_verify_writable_privileges(accounts)?; + withdraw_fees_verify_signer_privileges(accounts)?; + Ok(()) +} pub const DEPOSIT_STAKE_IX_ACCOUNTS_LEN: usize = 5; #[derive(Copy, Clone, Debug)] pub struct DepositStakeAccounts<'me, 'info> { @@ -1172,7 +1353,7 @@ pub struct DepositStakeAccounts<'me, 'info> { pub dest_token_to: &'me AccountInfo<'info>, ///The dest_token_mint token account collecting fees. PDA. Seeds = ['fee', dest_token_mint.pubkey] pub dest_token_fee_token_account: &'me AccountInfo<'info>, - ///Output token mint. If this is wrapped SOL, the account can be set to read-only + ///Output token mint. If this is wrapped SOL, the account can be set to read-only. The deposit stake accounts slice follows. pub dest_token_mint: &'me AccountInfo<'info>, } #[derive(Copy, Clone, Debug)] @@ -1185,7 +1366,7 @@ pub struct DepositStakeKeys { pub dest_token_to: Pubkey, ///The dest_token_mint token account collecting fees. PDA. Seeds = ['fee', dest_token_mint.pubkey] pub dest_token_fee_token_account: Pubkey, - ///Output token mint. If this is wrapped SOL, the account can be set to read-only + ///Output token mint. If this is wrapped SOL, the account can be set to read-only. The deposit stake accounts slice follows. pub dest_token_mint: Pubkey, } impl From> for DepositStakeKeys { @@ -1296,27 +1477,45 @@ impl DepositStakeIxData { Ok(data) } } -pub fn deposit_stake_ix>(accounts: K) -> std::io::Result { - let keys: DepositStakeKeys = accounts.into(); +pub fn deposit_stake_ix_with_program_id( + program_id: Pubkey, + keys: DepositStakeKeys, +) -> std::io::Result { let metas: [AccountMeta; DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: DepositStakeIxData.try_to_vec()?, }) } -pub fn deposit_stake_invoke<'info>(accounts: DepositStakeAccounts<'_, 'info>) -> ProgramResult { - let ix = deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = accounts.into(); - invoke(&ix, &account_info) +pub fn deposit_stake_ix(keys: DepositStakeKeys) -> std::io::Result { + deposit_stake_ix_with_program_id(crate::ID, keys) +} +pub fn deposit_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: DepositStakeAccounts<'_, '_>, +) -> ProgramResult { + let keys: DepositStakeKeys = accounts.into(); + let ix = deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn deposit_stake_invoke(accounts: DepositStakeAccounts<'_, '_>) -> ProgramResult { + deposit_stake_invoke_with_program_id(crate::ID, accounts) +} +pub fn deposit_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: DepositStakeAccounts<'_, '_>, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let keys: DepositStakeKeys = accounts.into(); + let ix = deposit_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn deposit_stake_invoke_signed<'info>( - accounts: DepositStakeAccounts<'_, 'info>, +pub fn deposit_stake_invoke_signed( + accounts: DepositStakeAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = deposit_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; DEPOSIT_STAKE_IX_ACCOUNTS_LEN] = accounts.into(); - invoke_signed(&ix, &account_info, seeds) + deposit_stake_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn deposit_stake_verify_account_keys( accounts: DepositStakeAccounts<'_, '_>, @@ -1338,7 +1537,7 @@ pub fn deposit_stake_verify_account_keys( } Ok(()) } -pub fn deposit_stake_verify_account_privileges<'me, 'info>( +pub fn deposit_stake_verify_writable_privileges<'me, 'info>( accounts: DepositStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -1352,6 +1551,11 @@ pub fn deposit_stake_verify_account_privileges<'me, 'info>( return Err((should_be_writable, ProgramError::InvalidAccountData)); } } + Ok(()) +} +pub fn deposit_stake_verify_signer_privileges<'me, 'info>( + accounts: DepositStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_signer in [accounts.user] { if !should_be_signer.is_signer { return Err((should_be_signer, ProgramError::MissingRequiredSignature)); @@ -1359,3 +1563,888 @@ pub fn deposit_stake_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn deposit_stake_verify_account_privileges<'me, 'info>( + accounts: DepositStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + deposit_stake_verify_writable_privileges(accounts)?; + deposit_stake_verify_signer_privileges(accounts)?; + Ok(()) +} +pub const PREFUND_WITHDRAW_STAKE_IX_ACCOUNTS_LEN: usize = 16; +#[derive(Copy, Clone, Debug)] +pub struct PrefundWithdrawStakeAccounts<'me, 'info> { + ///The withdraw authority of stake_account. Needs to be mutable and system account to receive slumlord flash loan. + pub user: &'me AccountInfo<'info>, + ///The token account to burn src tokens from in order to withdraw stake + pub src_token_from: &'me AccountInfo<'info>, + ///The bridge stake account thats withdrawn and given to the user. PDA. seeds = ['bridge_stake', user.pubkey, SwapArgs.bridge_stake_seed]. Might be long-lived, make sure the seed is not already in use + pub bridge_stake: &'me AccountInfo<'info>, + ///Input LST token mint + pub src_token_mint: &'me AccountInfo<'info>, + ///The system account PDA that contains enough SOL to prefund 2 stake accounts for withdrawal. Someone must send SOL to here to initialize it. Seeds = ['prefunder'] + pub prefunder: &'me AccountInfo<'info>, + ///The slumdog stake account is split from bridge_stake upon stake withdraw and instant unstaked to repay slumlord's flash loan. create_with_seed(bridge_stake.pubkey, 'slumdog', stake_program). Might be long-lived, but should be not in use as long as bridge_stake is not in use + pub slumdog_stake: &'me AccountInfo<'info>, + ///Sanctum unstake program. unpXTU2Ndrc7WWNyEhQWe4udTzSibLPi25SXv2xbCHQ + pub unstakeit_program: &'me AccountInfo<'info>, + ///Sanctum unstake pool. FypPtwbY3FUfzJUtXHSyVRokVKG2jKtH29FmK4ebxRSd + pub unstake_pool: &'me AccountInfo<'info>, + ///Sanctum unstake pool SOL reserves. 3rBnnH9TTgd3xwu48rnzGsaQkSr1hR64nY71DrDt6VrQ + pub pool_sol_reserves: &'me AccountInfo<'info>, + ///Sanctum unstake pool Fee account. 5Pcu8WeQa3VbBz2vdBT49Rj4gbS4hsnfzuL1LmuRaKFY + pub unstake_fee: &'me AccountInfo<'info>, + ///Sanctum unstake pool stake account record for slumdog stake. PDA of sanctum unstake program. Seeds = [unstakePool.pubkey, slumdogStake.pubkey]. + pub slumdog_stake_acc_record: &'me AccountInfo<'info>, + ///Sanctum unstake pool protocol fee account. 2hN9UhvRFVfPYKL6rZJ5YiLEPCLTpN755pgwDJHWgFbU + pub unstake_protocol_fee: &'me AccountInfo<'info>, + ///Sanctum unstake pool protocol fee destination. unstakeProtocolFee.destination + pub unstake_protocol_fee_dest: &'me AccountInfo<'info>, + ///sysvar clock + pub clock: &'me AccountInfo<'info>, + ///stake program + pub stake_program: &'me AccountInfo<'info>, + ///System program. The withdraw stake accounts slices follow. + pub system_program: &'me AccountInfo<'info>, +} +#[derive(Copy, Clone, Debug)] +pub struct PrefundWithdrawStakeKeys { + ///The withdraw authority of stake_account. Needs to be mutable and system account to receive slumlord flash loan. + pub user: Pubkey, + ///The token account to burn src tokens from in order to withdraw stake + pub src_token_from: Pubkey, + ///The bridge stake account thats withdrawn and given to the user. PDA. seeds = ['bridge_stake', user.pubkey, SwapArgs.bridge_stake_seed]. Might be long-lived, make sure the seed is not already in use + pub bridge_stake: Pubkey, + ///Input LST token mint + pub src_token_mint: Pubkey, + ///The system account PDA that contains enough SOL to prefund 2 stake accounts for withdrawal. Someone must send SOL to here to initialize it. Seeds = ['prefunder'] + pub prefunder: Pubkey, + ///The slumdog stake account is split from bridge_stake upon stake withdraw and instant unstaked to repay slumlord's flash loan. create_with_seed(bridge_stake.pubkey, 'slumdog', stake_program). Might be long-lived, but should be not in use as long as bridge_stake is not in use + pub slumdog_stake: Pubkey, + ///Sanctum unstake program. unpXTU2Ndrc7WWNyEhQWe4udTzSibLPi25SXv2xbCHQ + pub unstakeit_program: Pubkey, + ///Sanctum unstake pool. FypPtwbY3FUfzJUtXHSyVRokVKG2jKtH29FmK4ebxRSd + pub unstake_pool: Pubkey, + ///Sanctum unstake pool SOL reserves. 3rBnnH9TTgd3xwu48rnzGsaQkSr1hR64nY71DrDt6VrQ + pub pool_sol_reserves: Pubkey, + ///Sanctum unstake pool Fee account. 5Pcu8WeQa3VbBz2vdBT49Rj4gbS4hsnfzuL1LmuRaKFY + pub unstake_fee: Pubkey, + ///Sanctum unstake pool stake account record for slumdog stake. PDA of sanctum unstake program. Seeds = [unstakePool.pubkey, slumdogStake.pubkey]. + pub slumdog_stake_acc_record: Pubkey, + ///Sanctum unstake pool protocol fee account. 2hN9UhvRFVfPYKL6rZJ5YiLEPCLTpN755pgwDJHWgFbU + pub unstake_protocol_fee: Pubkey, + ///Sanctum unstake pool protocol fee destination. unstakeProtocolFee.destination + pub unstake_protocol_fee_dest: Pubkey, + ///sysvar clock + pub clock: Pubkey, + ///stake program + pub stake_program: Pubkey, + ///System program. The withdraw stake accounts slices follow. + pub system_program: Pubkey, +} +impl From> for PrefundWithdrawStakeKeys { + fn from(accounts: PrefundWithdrawStakeAccounts) -> Self { + Self { + user: *accounts.user.key, + src_token_from: *accounts.src_token_from.key, + bridge_stake: *accounts.bridge_stake.key, + src_token_mint: *accounts.src_token_mint.key, + prefunder: *accounts.prefunder.key, + slumdog_stake: *accounts.slumdog_stake.key, + unstakeit_program: *accounts.unstakeit_program.key, + unstake_pool: *accounts.unstake_pool.key, + pool_sol_reserves: *accounts.pool_sol_reserves.key, + unstake_fee: *accounts.unstake_fee.key, + slumdog_stake_acc_record: *accounts.slumdog_stake_acc_record.key, + unstake_protocol_fee: *accounts.unstake_protocol_fee.key, + unstake_protocol_fee_dest: *accounts.unstake_protocol_fee_dest.key, + clock: *accounts.clock.key, + stake_program: *accounts.stake_program.key, + system_program: *accounts.system_program.key, + } + } +} +impl From for [AccountMeta; PREFUND_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] { + fn from(keys: PrefundWithdrawStakeKeys) -> Self { + [ + AccountMeta { + pubkey: keys.user, + is_signer: true, + is_writable: true, + }, + AccountMeta { + pubkey: keys.src_token_from, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.bridge_stake, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.src_token_mint, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.prefunder, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.slumdog_stake, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.unstakeit_program, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.unstake_pool, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.pool_sol_reserves, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.unstake_fee, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.slumdog_stake_acc_record, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.unstake_protocol_fee, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.unstake_protocol_fee_dest, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.clock, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.stake_program, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.system_program, + is_signer: false, + is_writable: false, + }, + ] + } +} +impl From<[Pubkey; PREFUND_WITHDRAW_STAKE_IX_ACCOUNTS_LEN]> for PrefundWithdrawStakeKeys { + fn from(pubkeys: [Pubkey; PREFUND_WITHDRAW_STAKE_IX_ACCOUNTS_LEN]) -> Self { + Self { + user: pubkeys[0], + src_token_from: pubkeys[1], + bridge_stake: pubkeys[2], + src_token_mint: pubkeys[3], + prefunder: pubkeys[4], + slumdog_stake: pubkeys[5], + unstakeit_program: pubkeys[6], + unstake_pool: pubkeys[7], + pool_sol_reserves: pubkeys[8], + unstake_fee: pubkeys[9], + slumdog_stake_acc_record: pubkeys[10], + unstake_protocol_fee: pubkeys[11], + unstake_protocol_fee_dest: pubkeys[12], + clock: pubkeys[13], + stake_program: pubkeys[14], + system_program: pubkeys[15], + } + } +} +impl<'info> From> + for [AccountInfo<'info>; PREFUND_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] +{ + fn from(accounts: PrefundWithdrawStakeAccounts<'_, 'info>) -> Self { + [ + accounts.user.clone(), + accounts.src_token_from.clone(), + accounts.bridge_stake.clone(), + accounts.src_token_mint.clone(), + accounts.prefunder.clone(), + accounts.slumdog_stake.clone(), + accounts.unstakeit_program.clone(), + accounts.unstake_pool.clone(), + accounts.pool_sol_reserves.clone(), + accounts.unstake_fee.clone(), + accounts.slumdog_stake_acc_record.clone(), + accounts.unstake_protocol_fee.clone(), + accounts.unstake_protocol_fee_dest.clone(), + accounts.clock.clone(), + accounts.stake_program.clone(), + accounts.system_program.clone(), + ] + } +} +impl<'me, 'info> From<&'me [AccountInfo<'info>; PREFUND_WITHDRAW_STAKE_IX_ACCOUNTS_LEN]> + for PrefundWithdrawStakeAccounts<'me, 'info> +{ + fn from(arr: &'me [AccountInfo<'info>; PREFUND_WITHDRAW_STAKE_IX_ACCOUNTS_LEN]) -> Self { + Self { + user: &arr[0], + src_token_from: &arr[1], + bridge_stake: &arr[2], + src_token_mint: &arr[3], + prefunder: &arr[4], + slumdog_stake: &arr[5], + unstakeit_program: &arr[6], + unstake_pool: &arr[7], + pool_sol_reserves: &arr[8], + unstake_fee: &arr[9], + slumdog_stake_acc_record: &arr[10], + unstake_protocol_fee: &arr[11], + unstake_protocol_fee_dest: &arr[12], + clock: &arr[13], + stake_program: &arr[14], + system_program: &arr[15], + } + } +} +pub const PREFUND_WITHDRAW_STAKE_IX_DISCM: u8 = 6u8; +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct PrefundWithdrawStakeIxArgs { + pub args: SwapViaStakeArgs, +} +#[derive(Clone, Debug, PartialEq)] +pub struct PrefundWithdrawStakeIxData(pub PrefundWithdrawStakeIxArgs); +impl From for PrefundWithdrawStakeIxData { + fn from(args: PrefundWithdrawStakeIxArgs) -> Self { + Self(args) + } +} +impl PrefundWithdrawStakeIxData { + pub fn deserialize(buf: &[u8]) -> std::io::Result { + let mut reader = buf; + let mut maybe_discm_buf = [0u8; 1]; + reader.read_exact(&mut maybe_discm_buf)?; + let maybe_discm = maybe_discm_buf[0]; + if maybe_discm != PREFUND_WITHDRAW_STAKE_IX_DISCM { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!( + "discm does not match. Expected: {:?}. Received: {:?}", + PREFUND_WITHDRAW_STAKE_IX_DISCM, maybe_discm + ), + )); + } + Ok(Self(PrefundWithdrawStakeIxArgs::deserialize(&mut reader)?)) + } + pub fn serialize(&self, mut writer: W) -> std::io::Result<()> { + writer.write_all(&[PREFUND_WITHDRAW_STAKE_IX_DISCM])?; + self.0.serialize(&mut writer) + } + pub fn try_to_vec(&self) -> std::io::Result> { + let mut data = Vec::new(); + self.serialize(&mut data)?; + Ok(data) + } +} +pub fn prefund_withdraw_stake_ix_with_program_id( + program_id: Pubkey, + keys: PrefundWithdrawStakeKeys, + args: PrefundWithdrawStakeIxArgs, +) -> std::io::Result { + let metas: [AccountMeta; PREFUND_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = keys.into(); + let data: PrefundWithdrawStakeIxData = args.into(); + Ok(Instruction { + program_id, + accounts: Vec::from(metas), + data: data.try_to_vec()?, + }) +} +pub fn prefund_withdraw_stake_ix( + keys: PrefundWithdrawStakeKeys, + args: PrefundWithdrawStakeIxArgs, +) -> std::io::Result { + prefund_withdraw_stake_ix_with_program_id(crate::ID, keys, args) +} +pub fn prefund_withdraw_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: PrefundWithdrawStakeAccounts<'_, '_>, + args: PrefundWithdrawStakeIxArgs, +) -> ProgramResult { + let keys: PrefundWithdrawStakeKeys = accounts.into(); + let ix = prefund_withdraw_stake_ix_with_program_id(program_id, keys, args)?; + invoke_instruction(&ix, accounts) +} +pub fn prefund_withdraw_stake_invoke( + accounts: PrefundWithdrawStakeAccounts<'_, '_>, + args: PrefundWithdrawStakeIxArgs, +) -> ProgramResult { + prefund_withdraw_stake_invoke_with_program_id(crate::ID, accounts, args) +} +pub fn prefund_withdraw_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: PrefundWithdrawStakeAccounts<'_, '_>, + args: PrefundWithdrawStakeIxArgs, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let keys: PrefundWithdrawStakeKeys = accounts.into(); + let ix = prefund_withdraw_stake_ix_with_program_id(program_id, keys, args)?; + invoke_instruction_signed(&ix, accounts, seeds) +} +pub fn prefund_withdraw_stake_invoke_signed( + accounts: PrefundWithdrawStakeAccounts<'_, '_>, + args: PrefundWithdrawStakeIxArgs, + seeds: &[&[&[u8]]], +) -> ProgramResult { + prefund_withdraw_stake_invoke_signed_with_program_id(crate::ID, accounts, args, seeds) +} +pub fn prefund_withdraw_stake_verify_account_keys( + accounts: PrefundWithdrawStakeAccounts<'_, '_>, + keys: PrefundWithdrawStakeKeys, +) -> Result<(), (Pubkey, Pubkey)> { + for (actual, expected) in [ + (accounts.user.key, &keys.user), + (accounts.src_token_from.key, &keys.src_token_from), + (accounts.bridge_stake.key, &keys.bridge_stake), + (accounts.src_token_mint.key, &keys.src_token_mint), + (accounts.prefunder.key, &keys.prefunder), + (accounts.slumdog_stake.key, &keys.slumdog_stake), + (accounts.unstakeit_program.key, &keys.unstakeit_program), + (accounts.unstake_pool.key, &keys.unstake_pool), + (accounts.pool_sol_reserves.key, &keys.pool_sol_reserves), + (accounts.unstake_fee.key, &keys.unstake_fee), + ( + accounts.slumdog_stake_acc_record.key, + &keys.slumdog_stake_acc_record, + ), + ( + accounts.unstake_protocol_fee.key, + &keys.unstake_protocol_fee, + ), + ( + accounts.unstake_protocol_fee_dest.key, + &keys.unstake_protocol_fee_dest, + ), + (accounts.clock.key, &keys.clock), + (accounts.stake_program.key, &keys.stake_program), + (accounts.system_program.key, &keys.system_program), + ] { + if actual != expected { + return Err((*actual, *expected)); + } + } + Ok(()) +} +pub fn prefund_withdraw_stake_verify_writable_privileges<'me, 'info>( + accounts: PrefundWithdrawStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + for should_be_writable in [ + accounts.user, + accounts.src_token_from, + accounts.bridge_stake, + accounts.src_token_mint, + accounts.prefunder, + accounts.slumdog_stake, + accounts.unstake_pool, + accounts.pool_sol_reserves, + accounts.slumdog_stake_acc_record, + accounts.unstake_protocol_fee_dest, + ] { + if !should_be_writable.is_writable { + return Err((should_be_writable, ProgramError::InvalidAccountData)); + } + } + Ok(()) +} +pub fn prefund_withdraw_stake_verify_signer_privileges<'me, 'info>( + accounts: PrefundWithdrawStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + for should_be_signer in [accounts.user] { + if !should_be_signer.is_signer { + return Err((should_be_signer, ProgramError::MissingRequiredSignature)); + } + } + Ok(()) +} +pub fn prefund_withdraw_stake_verify_account_privileges<'me, 'info>( + accounts: PrefundWithdrawStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + prefund_withdraw_stake_verify_writable_privileges(accounts)?; + prefund_withdraw_stake_verify_signer_privileges(accounts)?; + Ok(()) +} +pub const PREFUND_SWAP_VIA_STAKE_IX_ACCOUNTS_LEN: usize = 19; +#[derive(Copy, Clone, Debug)] +pub struct PrefundSwapViaStakeAccounts<'me, 'info> { + ///The authority of src_token_from, mutable system account. Prefunds the rent for the stake accounts, amount is refunded via instant unstake. + pub user: &'me AccountInfo<'info>, + ///The token account to swap src tokens from + pub src_token_from: &'me AccountInfo<'info>, + ///The token account to receive dest tokens to + pub dest_token_to: &'me AccountInfo<'info>, + ///The bridge stake account thats withdrawn then deposited. PDA. seeds = ['bridge_stake', user.pubkey, SwapArgs.bridge_stake_seed]. Might be long-lived, make sure the seed is not already in use + pub bridge_stake: &'me AccountInfo<'info>, + ///The dest_token_mint token account collecting fees. PDA. Seeds = ['fee', dest_token_mint.pubkey] + pub dest_token_fee_token_account: &'me AccountInfo<'info>, + ///Input token mint. If this is wrapped SOL, the account can be set to read-only + pub src_token_mint: &'me AccountInfo<'info>, + ///Output token mint. If this is wrapped SOL, the account can be set to read-only + pub dest_token_mint: &'me AccountInfo<'info>, + ///The system account PDA that contains enough SOL to prefund 2 stake accounts for withdrawal. Someone must send SOL to here to initialize it. Seeds = ['prefunder'] + pub prefunder: &'me AccountInfo<'info>, + ///The slumdog stake account is split from bridge_stake upon stake withdraw and instant unstaked to refund user. create_with_seed(bridge_stake.pubkey, 'slumdog', stake_program). Might be long-lived, but should be not in use as long as bridge_stake is not in use + pub slumdog_stake: &'me AccountInfo<'info>, + ///Sanctum unstake program. unpXTU2Ndrc7WWNyEhQWe4udTzSibLPi25SXv2xbCHQ + pub unstakeit_program: &'me AccountInfo<'info>, + ///Sanctum unstake pool. FypPtwbY3FUfzJUtXHSyVRokVKG2jKtH29FmK4ebxRSd + pub unstake_pool: &'me AccountInfo<'info>, + ///Sanctum unstake pool SOL reserves. 3rBnnH9TTgd3xwu48rnzGsaQkSr1hR64nY71DrDt6VrQ + pub pool_sol_reserves: &'me AccountInfo<'info>, + ///Sanctum unstake pool Fee account. 5Pcu8WeQa3VbBz2vdBT49Rj4gbS4hsnfzuL1LmuRaKFY + pub unstake_fee: &'me AccountInfo<'info>, + ///Sanctum unstake pool stake account record for slumdog stake. PDA of sanctum unstake program. Seeds = [unstakePool.pubkey, slumdogStake.pubkey]. + pub slumdog_stake_acc_record: &'me AccountInfo<'info>, + ///Sanctum unstake pool protocol fee account. 2hN9UhvRFVfPYKL6rZJ5YiLEPCLTpN755pgwDJHWgFbU + pub unstake_protocol_fee: &'me AccountInfo<'info>, + ///Sanctum unstake pool protocol fee destination. unstakeProtocolFee.destination + pub unstake_protocol_fee_dest: &'me AccountInfo<'info>, + ///sysvar clock + pub clock: &'me AccountInfo<'info>, + ///stake program + pub stake_program: &'me AccountInfo<'info>, + ///System program. The withdraw stake and deposit stake accounts slices follow. + pub system_program: &'me AccountInfo<'info>, +} +#[derive(Copy, Clone, Debug)] +pub struct PrefundSwapViaStakeKeys { + ///The authority of src_token_from, mutable system account. Prefunds the rent for the stake accounts, amount is refunded via instant unstake. + pub user: Pubkey, + ///The token account to swap src tokens from + pub src_token_from: Pubkey, + ///The token account to receive dest tokens to + pub dest_token_to: Pubkey, + ///The bridge stake account thats withdrawn then deposited. PDA. seeds = ['bridge_stake', user.pubkey, SwapArgs.bridge_stake_seed]. Might be long-lived, make sure the seed is not already in use + pub bridge_stake: Pubkey, + ///The dest_token_mint token account collecting fees. PDA. Seeds = ['fee', dest_token_mint.pubkey] + pub dest_token_fee_token_account: Pubkey, + ///Input token mint. If this is wrapped SOL, the account can be set to read-only + pub src_token_mint: Pubkey, + ///Output token mint. If this is wrapped SOL, the account can be set to read-only + pub dest_token_mint: Pubkey, + ///The system account PDA that contains enough SOL to prefund 2 stake accounts for withdrawal. Someone must send SOL to here to initialize it. Seeds = ['prefunder'] + pub prefunder: Pubkey, + ///The slumdog stake account is split from bridge_stake upon stake withdraw and instant unstaked to refund user. create_with_seed(bridge_stake.pubkey, 'slumdog', stake_program). Might be long-lived, but should be not in use as long as bridge_stake is not in use + pub slumdog_stake: Pubkey, + ///Sanctum unstake program. unpXTU2Ndrc7WWNyEhQWe4udTzSibLPi25SXv2xbCHQ + pub unstakeit_program: Pubkey, + ///Sanctum unstake pool. FypPtwbY3FUfzJUtXHSyVRokVKG2jKtH29FmK4ebxRSd + pub unstake_pool: Pubkey, + ///Sanctum unstake pool SOL reserves. 3rBnnH9TTgd3xwu48rnzGsaQkSr1hR64nY71DrDt6VrQ + pub pool_sol_reserves: Pubkey, + ///Sanctum unstake pool Fee account. 5Pcu8WeQa3VbBz2vdBT49Rj4gbS4hsnfzuL1LmuRaKFY + pub unstake_fee: Pubkey, + ///Sanctum unstake pool stake account record for slumdog stake. PDA of sanctum unstake program. Seeds = [unstakePool.pubkey, slumdogStake.pubkey]. + pub slumdog_stake_acc_record: Pubkey, + ///Sanctum unstake pool protocol fee account. 2hN9UhvRFVfPYKL6rZJ5YiLEPCLTpN755pgwDJHWgFbU + pub unstake_protocol_fee: Pubkey, + ///Sanctum unstake pool protocol fee destination. unstakeProtocolFee.destination + pub unstake_protocol_fee_dest: Pubkey, + ///sysvar clock + pub clock: Pubkey, + ///stake program + pub stake_program: Pubkey, + ///System program. The withdraw stake and deposit stake accounts slices follow. + pub system_program: Pubkey, +} +impl From> for PrefundSwapViaStakeKeys { + fn from(accounts: PrefundSwapViaStakeAccounts) -> Self { + Self { + user: *accounts.user.key, + src_token_from: *accounts.src_token_from.key, + dest_token_to: *accounts.dest_token_to.key, + bridge_stake: *accounts.bridge_stake.key, + dest_token_fee_token_account: *accounts.dest_token_fee_token_account.key, + src_token_mint: *accounts.src_token_mint.key, + dest_token_mint: *accounts.dest_token_mint.key, + prefunder: *accounts.prefunder.key, + slumdog_stake: *accounts.slumdog_stake.key, + unstakeit_program: *accounts.unstakeit_program.key, + unstake_pool: *accounts.unstake_pool.key, + pool_sol_reserves: *accounts.pool_sol_reserves.key, + unstake_fee: *accounts.unstake_fee.key, + slumdog_stake_acc_record: *accounts.slumdog_stake_acc_record.key, + unstake_protocol_fee: *accounts.unstake_protocol_fee.key, + unstake_protocol_fee_dest: *accounts.unstake_protocol_fee_dest.key, + clock: *accounts.clock.key, + stake_program: *accounts.stake_program.key, + system_program: *accounts.system_program.key, + } + } +} +impl From for [AccountMeta; PREFUND_SWAP_VIA_STAKE_IX_ACCOUNTS_LEN] { + fn from(keys: PrefundSwapViaStakeKeys) -> Self { + [ + AccountMeta { + pubkey: keys.user, + is_signer: true, + is_writable: true, + }, + AccountMeta { + pubkey: keys.src_token_from, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.dest_token_to, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.bridge_stake, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.dest_token_fee_token_account, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.src_token_mint, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.dest_token_mint, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.prefunder, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.slumdog_stake, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.unstakeit_program, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.unstake_pool, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.pool_sol_reserves, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.unstake_fee, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.slumdog_stake_acc_record, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.unstake_protocol_fee, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.unstake_protocol_fee_dest, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: keys.clock, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.stake_program, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.system_program, + is_signer: false, + is_writable: false, + }, + ] + } +} +impl From<[Pubkey; PREFUND_SWAP_VIA_STAKE_IX_ACCOUNTS_LEN]> for PrefundSwapViaStakeKeys { + fn from(pubkeys: [Pubkey; PREFUND_SWAP_VIA_STAKE_IX_ACCOUNTS_LEN]) -> Self { + Self { + user: pubkeys[0], + src_token_from: pubkeys[1], + dest_token_to: pubkeys[2], + bridge_stake: pubkeys[3], + dest_token_fee_token_account: pubkeys[4], + src_token_mint: pubkeys[5], + dest_token_mint: pubkeys[6], + prefunder: pubkeys[7], + slumdog_stake: pubkeys[8], + unstakeit_program: pubkeys[9], + unstake_pool: pubkeys[10], + pool_sol_reserves: pubkeys[11], + unstake_fee: pubkeys[12], + slumdog_stake_acc_record: pubkeys[13], + unstake_protocol_fee: pubkeys[14], + unstake_protocol_fee_dest: pubkeys[15], + clock: pubkeys[16], + stake_program: pubkeys[17], + system_program: pubkeys[18], + } + } +} +impl<'info> From> + for [AccountInfo<'info>; PREFUND_SWAP_VIA_STAKE_IX_ACCOUNTS_LEN] +{ + fn from(accounts: PrefundSwapViaStakeAccounts<'_, 'info>) -> Self { + [ + accounts.user.clone(), + accounts.src_token_from.clone(), + accounts.dest_token_to.clone(), + accounts.bridge_stake.clone(), + accounts.dest_token_fee_token_account.clone(), + accounts.src_token_mint.clone(), + accounts.dest_token_mint.clone(), + accounts.prefunder.clone(), + accounts.slumdog_stake.clone(), + accounts.unstakeit_program.clone(), + accounts.unstake_pool.clone(), + accounts.pool_sol_reserves.clone(), + accounts.unstake_fee.clone(), + accounts.slumdog_stake_acc_record.clone(), + accounts.unstake_protocol_fee.clone(), + accounts.unstake_protocol_fee_dest.clone(), + accounts.clock.clone(), + accounts.stake_program.clone(), + accounts.system_program.clone(), + ] + } +} +impl<'me, 'info> From<&'me [AccountInfo<'info>; PREFUND_SWAP_VIA_STAKE_IX_ACCOUNTS_LEN]> + for PrefundSwapViaStakeAccounts<'me, 'info> +{ + fn from(arr: &'me [AccountInfo<'info>; PREFUND_SWAP_VIA_STAKE_IX_ACCOUNTS_LEN]) -> Self { + Self { + user: &arr[0], + src_token_from: &arr[1], + dest_token_to: &arr[2], + bridge_stake: &arr[3], + dest_token_fee_token_account: &arr[4], + src_token_mint: &arr[5], + dest_token_mint: &arr[6], + prefunder: &arr[7], + slumdog_stake: &arr[8], + unstakeit_program: &arr[9], + unstake_pool: &arr[10], + pool_sol_reserves: &arr[11], + unstake_fee: &arr[12], + slumdog_stake_acc_record: &arr[13], + unstake_protocol_fee: &arr[14], + unstake_protocol_fee_dest: &arr[15], + clock: &arr[16], + stake_program: &arr[17], + system_program: &arr[18], + } + } +} +pub const PREFUND_SWAP_VIA_STAKE_IX_DISCM: u8 = 7u8; +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct PrefundSwapViaStakeIxArgs { + pub args: SwapViaStakeArgs, +} +#[derive(Clone, Debug, PartialEq)] +pub struct PrefundSwapViaStakeIxData(pub PrefundSwapViaStakeIxArgs); +impl From for PrefundSwapViaStakeIxData { + fn from(args: PrefundSwapViaStakeIxArgs) -> Self { + Self(args) + } +} +impl PrefundSwapViaStakeIxData { + pub fn deserialize(buf: &[u8]) -> std::io::Result { + let mut reader = buf; + let mut maybe_discm_buf = [0u8; 1]; + reader.read_exact(&mut maybe_discm_buf)?; + let maybe_discm = maybe_discm_buf[0]; + if maybe_discm != PREFUND_SWAP_VIA_STAKE_IX_DISCM { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!( + "discm does not match. Expected: {:?}. Received: {:?}", + PREFUND_SWAP_VIA_STAKE_IX_DISCM, maybe_discm + ), + )); + } + Ok(Self(PrefundSwapViaStakeIxArgs::deserialize(&mut reader)?)) + } + pub fn serialize(&self, mut writer: W) -> std::io::Result<()> { + writer.write_all(&[PREFUND_SWAP_VIA_STAKE_IX_DISCM])?; + self.0.serialize(&mut writer) + } + pub fn try_to_vec(&self) -> std::io::Result> { + let mut data = Vec::new(); + self.serialize(&mut data)?; + Ok(data) + } +} +pub fn prefund_swap_via_stake_ix_with_program_id( + program_id: Pubkey, + keys: PrefundSwapViaStakeKeys, + args: PrefundSwapViaStakeIxArgs, +) -> std::io::Result { + let metas: [AccountMeta; PREFUND_SWAP_VIA_STAKE_IX_ACCOUNTS_LEN] = keys.into(); + let data: PrefundSwapViaStakeIxData = args.into(); + Ok(Instruction { + program_id, + accounts: Vec::from(metas), + data: data.try_to_vec()?, + }) +} +pub fn prefund_swap_via_stake_ix( + keys: PrefundSwapViaStakeKeys, + args: PrefundSwapViaStakeIxArgs, +) -> std::io::Result { + prefund_swap_via_stake_ix_with_program_id(crate::ID, keys, args) +} +pub fn prefund_swap_via_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: PrefundSwapViaStakeAccounts<'_, '_>, + args: PrefundSwapViaStakeIxArgs, +) -> ProgramResult { + let keys: PrefundSwapViaStakeKeys = accounts.into(); + let ix = prefund_swap_via_stake_ix_with_program_id(program_id, keys, args)?; + invoke_instruction(&ix, accounts) +} +pub fn prefund_swap_via_stake_invoke( + accounts: PrefundSwapViaStakeAccounts<'_, '_>, + args: PrefundSwapViaStakeIxArgs, +) -> ProgramResult { + prefund_swap_via_stake_invoke_with_program_id(crate::ID, accounts, args) +} +pub fn prefund_swap_via_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: PrefundSwapViaStakeAccounts<'_, '_>, + args: PrefundSwapViaStakeIxArgs, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let keys: PrefundSwapViaStakeKeys = accounts.into(); + let ix = prefund_swap_via_stake_ix_with_program_id(program_id, keys, args)?; + invoke_instruction_signed(&ix, accounts, seeds) +} +pub fn prefund_swap_via_stake_invoke_signed( + accounts: PrefundSwapViaStakeAccounts<'_, '_>, + args: PrefundSwapViaStakeIxArgs, + seeds: &[&[&[u8]]], +) -> ProgramResult { + prefund_swap_via_stake_invoke_signed_with_program_id(crate::ID, accounts, args, seeds) +} +pub fn prefund_swap_via_stake_verify_account_keys( + accounts: PrefundSwapViaStakeAccounts<'_, '_>, + keys: PrefundSwapViaStakeKeys, +) -> Result<(), (Pubkey, Pubkey)> { + for (actual, expected) in [ + (accounts.user.key, &keys.user), + (accounts.src_token_from.key, &keys.src_token_from), + (accounts.dest_token_to.key, &keys.dest_token_to), + (accounts.bridge_stake.key, &keys.bridge_stake), + ( + accounts.dest_token_fee_token_account.key, + &keys.dest_token_fee_token_account, + ), + (accounts.src_token_mint.key, &keys.src_token_mint), + (accounts.dest_token_mint.key, &keys.dest_token_mint), + (accounts.prefunder.key, &keys.prefunder), + (accounts.slumdog_stake.key, &keys.slumdog_stake), + (accounts.unstakeit_program.key, &keys.unstakeit_program), + (accounts.unstake_pool.key, &keys.unstake_pool), + (accounts.pool_sol_reserves.key, &keys.pool_sol_reserves), + (accounts.unstake_fee.key, &keys.unstake_fee), + ( + accounts.slumdog_stake_acc_record.key, + &keys.slumdog_stake_acc_record, + ), + ( + accounts.unstake_protocol_fee.key, + &keys.unstake_protocol_fee, + ), + ( + accounts.unstake_protocol_fee_dest.key, + &keys.unstake_protocol_fee_dest, + ), + (accounts.clock.key, &keys.clock), + (accounts.stake_program.key, &keys.stake_program), + (accounts.system_program.key, &keys.system_program), + ] { + if actual != expected { + return Err((*actual, *expected)); + } + } + Ok(()) +} +pub fn prefund_swap_via_stake_verify_writable_privileges<'me, 'info>( + accounts: PrefundSwapViaStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + for should_be_writable in [ + accounts.user, + accounts.src_token_from, + accounts.dest_token_to, + accounts.bridge_stake, + accounts.dest_token_fee_token_account, + accounts.src_token_mint, + accounts.dest_token_mint, + accounts.prefunder, + accounts.slumdog_stake, + accounts.unstake_pool, + accounts.pool_sol_reserves, + accounts.slumdog_stake_acc_record, + accounts.unstake_protocol_fee_dest, + ] { + if !should_be_writable.is_writable { + return Err((should_be_writable, ProgramError::InvalidAccountData)); + } + } + Ok(()) +} +pub fn prefund_swap_via_stake_verify_signer_privileges<'me, 'info>( + accounts: PrefundSwapViaStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + for should_be_signer in [accounts.user] { + if !should_be_signer.is_signer { + return Err((should_be_signer, ProgramError::MissingRequiredSignature)); + } + } + Ok(()) +} +pub fn prefund_swap_via_stake_verify_account_privileges<'me, 'info>( + accounts: PrefundSwapViaStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + prefund_swap_via_stake_verify_writable_privileges(accounts)?; + prefund_swap_via_stake_verify_signer_privileges(accounts)?; + Ok(()) +} diff --git a/interfaces/stakedex_interface/src/lib.rs b/interfaces/stakedex_interface/src/lib.rs index b8a57d1..eabb9e8 100644 --- a/interfaces/stakedex_interface/src/lib.rs +++ b/interfaces/stakedex_interface/src/lib.rs @@ -1,4 +1,6 @@ solana_program::declare_id!("stkitrT1Uoy18Dk1fTrgPw8W6MVzoCfYoAFT4MLsmhq"); +pub mod typedefs; +pub use typedefs::*; pub mod instructions; pub use instructions::*; pub mod errors; diff --git a/interfaces/stakedex_interface/src/typedefs.rs b/interfaces/stakedex_interface/src/typedefs.rs new file mode 100644 index 0000000..6e17b2b --- /dev/null +++ b/interfaces/stakedex_interface/src/typedefs.rs @@ -0,0 +1,7 @@ +use borsh::{BorshDeserialize, BorshSerialize}; +#[derive(Clone, Debug, BorshDeserialize, BorshSerialize, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SwapViaStakeArgs { + pub amount: u64, + pub bridge_stake_seed: u32, +} diff --git a/interfaces/stakedex_withdraw_stake_interface/Cargo.toml b/interfaces/stakedex_withdraw_stake_interface/Cargo.toml index 4182b12..d7ae5ff 100644 --- a/interfaces/stakedex_withdraw_stake_interface/Cargo.toml +++ b/interfaces/stakedex_withdraw_stake_interface/Cargo.toml @@ -6,9 +6,9 @@ edition = "2021" [dependencies.borsh] workspace = true -[dependencies.solana-program] -workspace = true - [dependencies.serde] optional = true workspace = true + +[dependencies.solana-program] +workspace = true diff --git a/interfaces/stakedex_withdraw_stake_interface/idl.json b/interfaces/stakedex_withdraw_stake_interface/idl.json index 05c46e8..b4508d7 100644 --- a/interfaces/stakedex_withdraw_stake_interface/idl.json +++ b/interfaces/stakedex_withdraw_stake_interface/idl.json @@ -224,6 +224,26 @@ "name": "withdrawStakeDepositAuthority", "isMut": false, "isSigner": false + }, + { + "name": "clock", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "stakeProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false } ], "args": [], diff --git a/interfaces/stakedex_withdraw_stake_interface/src/instructions.rs b/interfaces/stakedex_withdraw_stake_interface/src/instructions.rs index ae68974..a25bd15 100644 --- a/interfaces/stakedex_withdraw_stake_interface/src/instructions.rs +++ b/interfaces/stakedex_withdraw_stake_interface/src/instructions.rs @@ -49,6 +49,21 @@ impl StakedexWithdrawStakeProgramIx { Ok(data) } } +fn invoke_instruction<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>( + ix: &Instruction, + accounts: A, +) -> ProgramResult { + let account_info: [AccountInfo<'info>; N] = accounts.into(); + invoke(ix, &account_info) +} +fn invoke_instruction_signed<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>( + ix: &Instruction, + accounts: A, + seeds: &[&[&[u8]]], +) -> ProgramResult { + let account_info: [AccountInfo<'info>; N] = accounts.into(); + invoke_signed(ix, &account_info, seeds) +} pub const SOCEAN_STAKE_POOL_WITHDRAW_STAKE_IX_ACCOUNTS_LEN: usize = 10; #[derive(Copy, Clone, Debug)] pub struct SoceanStakePoolWithdrawStakeAccounts<'me, 'info> { @@ -235,33 +250,49 @@ impl SoceanStakePoolWithdrawStakeIxData { Ok(data) } } -pub fn socean_stake_pool_withdraw_stake_ix>( - accounts: K, +pub fn socean_stake_pool_withdraw_stake_ix_with_program_id( + program_id: Pubkey, + keys: SoceanStakePoolWithdrawStakeKeys, ) -> std::io::Result { - let keys: SoceanStakePoolWithdrawStakeKeys = accounts.into(); let metas: [AccountMeta; SOCEAN_STAKE_POOL_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: SoceanStakePoolWithdrawStakeIxData.try_to_vec()?, }) } -pub fn socean_stake_pool_withdraw_stake_invoke<'info>( - accounts: SoceanStakePoolWithdrawStakeAccounts<'_, 'info>, +pub fn socean_stake_pool_withdraw_stake_ix( + keys: SoceanStakePoolWithdrawStakeKeys, +) -> std::io::Result { + socean_stake_pool_withdraw_stake_ix_with_program_id(crate::ID, keys) +} +pub fn socean_stake_pool_withdraw_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: SoceanStakePoolWithdrawStakeAccounts<'_, '_>, +) -> ProgramResult { + let keys: SoceanStakePoolWithdrawStakeKeys = accounts.into(); + let ix = socean_stake_pool_withdraw_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn socean_stake_pool_withdraw_stake_invoke( + accounts: SoceanStakePoolWithdrawStakeAccounts<'_, '_>, +) -> ProgramResult { + socean_stake_pool_withdraw_stake_invoke_with_program_id(crate::ID, accounts) +} +pub fn socean_stake_pool_withdraw_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: SoceanStakePoolWithdrawStakeAccounts<'_, '_>, + seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = socean_stake_pool_withdraw_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; SOCEAN_STAKE_POOL_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + let keys: SoceanStakePoolWithdrawStakeKeys = accounts.into(); + let ix = socean_stake_pool_withdraw_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn socean_stake_pool_withdraw_stake_invoke_signed<'info>( - accounts: SoceanStakePoolWithdrawStakeAccounts<'_, 'info>, +pub fn socean_stake_pool_withdraw_stake_invoke_signed( + accounts: SoceanStakePoolWithdrawStakeAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = socean_stake_pool_withdraw_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; SOCEAN_STAKE_POOL_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + socean_stake_pool_withdraw_stake_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn socean_stake_pool_withdraw_stake_verify_account_keys( accounts: SoceanStakePoolWithdrawStakeAccounts<'_, '_>, @@ -303,7 +334,7 @@ pub fn socean_stake_pool_withdraw_stake_verify_account_keys( } Ok(()) } -pub fn socean_stake_pool_withdraw_stake_verify_account_privileges<'me, 'info>( +pub fn socean_stake_pool_withdraw_stake_verify_writable_privileges<'me, 'info>( accounts: SoceanStakePoolWithdrawStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -318,6 +349,12 @@ pub fn socean_stake_pool_withdraw_stake_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn socean_stake_pool_withdraw_stake_verify_account_privileges<'me, 'info>( + accounts: SoceanStakePoolWithdrawStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + socean_stake_pool_withdraw_stake_verify_writable_privileges(accounts)?; + Ok(()) +} pub const SPL_STAKE_POOL_WITHDRAW_STAKE_IX_ACCOUNTS_LEN: usize = 10; #[derive(Copy, Clone, Debug)] pub struct SplStakePoolWithdrawStakeAccounts<'me, 'info> { @@ -502,33 +539,49 @@ impl SplStakePoolWithdrawStakeIxData { Ok(data) } } -pub fn spl_stake_pool_withdraw_stake_ix>( - accounts: K, +pub fn spl_stake_pool_withdraw_stake_ix_with_program_id( + program_id: Pubkey, + keys: SplStakePoolWithdrawStakeKeys, ) -> std::io::Result { - let keys: SplStakePoolWithdrawStakeKeys = accounts.into(); let metas: [AccountMeta; SPL_STAKE_POOL_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: SplStakePoolWithdrawStakeIxData.try_to_vec()?, }) } -pub fn spl_stake_pool_withdraw_stake_invoke<'info>( - accounts: SplStakePoolWithdrawStakeAccounts<'_, 'info>, +pub fn spl_stake_pool_withdraw_stake_ix( + keys: SplStakePoolWithdrawStakeKeys, +) -> std::io::Result { + spl_stake_pool_withdraw_stake_ix_with_program_id(crate::ID, keys) +} +pub fn spl_stake_pool_withdraw_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: SplStakePoolWithdrawStakeAccounts<'_, '_>, +) -> ProgramResult { + let keys: SplStakePoolWithdrawStakeKeys = accounts.into(); + let ix = spl_stake_pool_withdraw_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn spl_stake_pool_withdraw_stake_invoke( + accounts: SplStakePoolWithdrawStakeAccounts<'_, '_>, +) -> ProgramResult { + spl_stake_pool_withdraw_stake_invoke_with_program_id(crate::ID, accounts) +} +pub fn spl_stake_pool_withdraw_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: SplStakePoolWithdrawStakeAccounts<'_, '_>, + seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = spl_stake_pool_withdraw_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; SPL_STAKE_POOL_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + let keys: SplStakePoolWithdrawStakeKeys = accounts.into(); + let ix = spl_stake_pool_withdraw_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn spl_stake_pool_withdraw_stake_invoke_signed<'info>( - accounts: SplStakePoolWithdrawStakeAccounts<'_, 'info>, +pub fn spl_stake_pool_withdraw_stake_invoke_signed( + accounts: SplStakePoolWithdrawStakeAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = spl_stake_pool_withdraw_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; SPL_STAKE_POOL_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + spl_stake_pool_withdraw_stake_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn spl_stake_pool_withdraw_stake_verify_account_keys( accounts: SplStakePoolWithdrawStakeAccounts<'_, '_>, @@ -570,7 +623,7 @@ pub fn spl_stake_pool_withdraw_stake_verify_account_keys( } Ok(()) } -pub fn spl_stake_pool_withdraw_stake_verify_account_privileges<'me, 'info>( +pub fn spl_stake_pool_withdraw_stake_verify_writable_privileges<'me, 'info>( accounts: SplStakePoolWithdrawStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -585,6 +638,12 @@ pub fn spl_stake_pool_withdraw_stake_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn spl_stake_pool_withdraw_stake_verify_account_privileges<'me, 'info>( + accounts: SplStakePoolWithdrawStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + spl_stake_pool_withdraw_stake_verify_writable_privileges(accounts)?; + Ok(()) +} pub const LIDO_WITHDRAW_STAKE_IX_ACCOUNTS_LEN: usize = 10; #[derive(Copy, Clone, Debug)] pub struct LidoWithdrawStakeAccounts<'me, 'info> { @@ -765,31 +824,45 @@ impl LidoWithdrawStakeIxData { Ok(data) } } -pub fn lido_withdraw_stake_ix>( - accounts: K, +pub fn lido_withdraw_stake_ix_with_program_id( + program_id: Pubkey, + keys: LidoWithdrawStakeKeys, ) -> std::io::Result { - let keys: LidoWithdrawStakeKeys = accounts.into(); let metas: [AccountMeta; LIDO_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: LidoWithdrawStakeIxData.try_to_vec()?, }) } -pub fn lido_withdraw_stake_invoke<'info>( - accounts: LidoWithdrawStakeAccounts<'_, 'info>, +pub fn lido_withdraw_stake_ix(keys: LidoWithdrawStakeKeys) -> std::io::Result { + lido_withdraw_stake_ix_with_program_id(crate::ID, keys) +} +pub fn lido_withdraw_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: LidoWithdrawStakeAccounts<'_, '_>, +) -> ProgramResult { + let keys: LidoWithdrawStakeKeys = accounts.into(); + let ix = lido_withdraw_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn lido_withdraw_stake_invoke(accounts: LidoWithdrawStakeAccounts<'_, '_>) -> ProgramResult { + lido_withdraw_stake_invoke_with_program_id(crate::ID, accounts) +} +pub fn lido_withdraw_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: LidoWithdrawStakeAccounts<'_, '_>, + seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = lido_withdraw_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; LIDO_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = accounts.into(); - invoke(&ix, &account_info) + let keys: LidoWithdrawStakeKeys = accounts.into(); + let ix = lido_withdraw_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) } -pub fn lido_withdraw_stake_invoke_signed<'info>( - accounts: LidoWithdrawStakeAccounts<'_, 'info>, +pub fn lido_withdraw_stake_invoke_signed( + accounts: LidoWithdrawStakeAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = lido_withdraw_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; LIDO_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = accounts.into(); - invoke_signed(&ix, &account_info, seeds) + lido_withdraw_stake_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn lido_withdraw_stake_verify_account_keys( accounts: LidoWithdrawStakeAccounts<'_, '_>, @@ -828,7 +901,7 @@ pub fn lido_withdraw_stake_verify_account_keys( } Ok(()) } -pub fn lido_withdraw_stake_verify_account_privileges<'me, 'info>( +pub fn lido_withdraw_stake_verify_writable_privileges<'me, 'info>( accounts: LidoWithdrawStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -842,7 +915,13 @@ pub fn lido_withdraw_stake_verify_account_privileges<'me, 'info>( } Ok(()) } -pub const MARINADE_WITHDRAW_STAKE_IX_ACCOUNTS_LEN: usize = 8; +pub fn lido_withdraw_stake_verify_account_privileges<'me, 'info>( + accounts: LidoWithdrawStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + lido_withdraw_stake_verify_writable_privileges(accounts)?; + Ok(()) +} +pub const MARINADE_WITHDRAW_STAKE_IX_ACCOUNTS_LEN: usize = 12; #[derive(Copy, Clone, Debug)] pub struct MarinadeWithdrawStakeAccounts<'me, 'info> { pub marinade_program: &'me AccountInfo<'info>, @@ -853,6 +932,10 @@ pub struct MarinadeWithdrawStakeAccounts<'me, 'info> { pub withdraw_stake_stake_list: &'me AccountInfo<'info>, pub withdraw_stake_withdraw_authority: &'me AccountInfo<'info>, pub withdraw_stake_deposit_authority: &'me AccountInfo<'info>, + pub clock: &'me AccountInfo<'info>, + pub token_program: &'me AccountInfo<'info>, + pub stake_program: &'me AccountInfo<'info>, + pub system_program: &'me AccountInfo<'info>, } #[derive(Copy, Clone, Debug)] pub struct MarinadeWithdrawStakeKeys { @@ -864,6 +947,10 @@ pub struct MarinadeWithdrawStakeKeys { pub withdraw_stake_stake_list: Pubkey, pub withdraw_stake_withdraw_authority: Pubkey, pub withdraw_stake_deposit_authority: Pubkey, + pub clock: Pubkey, + pub token_program: Pubkey, + pub stake_program: Pubkey, + pub system_program: Pubkey, } impl From> for MarinadeWithdrawStakeKeys { fn from(accounts: MarinadeWithdrawStakeAccounts) -> Self { @@ -876,6 +963,10 @@ impl From> for MarinadeWithdrawStakeKeys { withdraw_stake_stake_list: *accounts.withdraw_stake_stake_list.key, withdraw_stake_withdraw_authority: *accounts.withdraw_stake_withdraw_authority.key, withdraw_stake_deposit_authority: *accounts.withdraw_stake_deposit_authority.key, + clock: *accounts.clock.key, + token_program: *accounts.token_program.key, + stake_program: *accounts.stake_program.key, + system_program: *accounts.system_program.key, } } } @@ -922,6 +1013,26 @@ impl From for [AccountMeta; MARINADE_WITHDRAW_STAKE_I is_signer: false, is_writable: false, }, + AccountMeta { + pubkey: keys.clock, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.token_program, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.stake_program, + is_signer: false, + is_writable: false, + }, + AccountMeta { + pubkey: keys.system_program, + is_signer: false, + is_writable: false, + }, ] } } @@ -936,6 +1047,10 @@ impl From<[Pubkey; MARINADE_WITHDRAW_STAKE_IX_ACCOUNTS_LEN]> for MarinadeWithdra withdraw_stake_stake_list: pubkeys[5], withdraw_stake_withdraw_authority: pubkeys[6], withdraw_stake_deposit_authority: pubkeys[7], + clock: pubkeys[8], + token_program: pubkeys[9], + stake_program: pubkeys[10], + system_program: pubkeys[11], } } } @@ -952,6 +1067,10 @@ impl<'info> From> accounts.withdraw_stake_stake_list.clone(), accounts.withdraw_stake_withdraw_authority.clone(), accounts.withdraw_stake_deposit_authority.clone(), + accounts.clock.clone(), + accounts.token_program.clone(), + accounts.stake_program.clone(), + accounts.system_program.clone(), ] } } @@ -968,6 +1087,10 @@ impl<'me, 'info> From<&'me [AccountInfo<'info>; MARINADE_WITHDRAW_STAKE_IX_ACCOU withdraw_stake_stake_list: &arr[5], withdraw_stake_withdraw_authority: &arr[6], withdraw_stake_deposit_authority: &arr[7], + clock: &arr[8], + token_program: &arr[9], + stake_program: &arr[10], + system_program: &arr[11], } } } @@ -1000,33 +1123,47 @@ impl MarinadeWithdrawStakeIxData { Ok(data) } } -pub fn marinade_withdraw_stake_ix>( - accounts: K, +pub fn marinade_withdraw_stake_ix_with_program_id( + program_id: Pubkey, + keys: MarinadeWithdrawStakeKeys, ) -> std::io::Result { - let keys: MarinadeWithdrawStakeKeys = accounts.into(); let metas: [AccountMeta; MARINADE_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = keys.into(); Ok(Instruction { - program_id: crate::ID, + program_id, accounts: Vec::from(metas), data: MarinadeWithdrawStakeIxData.try_to_vec()?, }) } -pub fn marinade_withdraw_stake_invoke<'info>( - accounts: MarinadeWithdrawStakeAccounts<'_, 'info>, +pub fn marinade_withdraw_stake_ix(keys: MarinadeWithdrawStakeKeys) -> std::io::Result { + marinade_withdraw_stake_ix_with_program_id(crate::ID, keys) +} +pub fn marinade_withdraw_stake_invoke_with_program_id( + program_id: Pubkey, + accounts: MarinadeWithdrawStakeAccounts<'_, '_>, +) -> ProgramResult { + let keys: MarinadeWithdrawStakeKeys = accounts.into(); + let ix = marinade_withdraw_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction(&ix, accounts) +} +pub fn marinade_withdraw_stake_invoke( + accounts: MarinadeWithdrawStakeAccounts<'_, '_>, ) -> ProgramResult { - let ix = marinade_withdraw_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; MARINADE_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke(&ix, &account_info) + marinade_withdraw_stake_invoke_with_program_id(crate::ID, accounts) } -pub fn marinade_withdraw_stake_invoke_signed<'info>( - accounts: MarinadeWithdrawStakeAccounts<'_, 'info>, +pub fn marinade_withdraw_stake_invoke_signed_with_program_id( + program_id: Pubkey, + accounts: MarinadeWithdrawStakeAccounts<'_, '_>, seeds: &[&[&[u8]]], ) -> ProgramResult { - let ix = marinade_withdraw_stake_ix(accounts)?; - let account_info: [AccountInfo<'info>; MARINADE_WITHDRAW_STAKE_IX_ACCOUNTS_LEN] = - accounts.into(); - invoke_signed(&ix, &account_info, seeds) + let keys: MarinadeWithdrawStakeKeys = accounts.into(); + let ix = marinade_withdraw_stake_ix_with_program_id(program_id, keys)?; + invoke_instruction_signed(&ix, accounts, seeds) +} +pub fn marinade_withdraw_stake_invoke_signed( + accounts: MarinadeWithdrawStakeAccounts<'_, '_>, + seeds: &[&[&[u8]]], +) -> ProgramResult { + marinade_withdraw_stake_invoke_signed_with_program_id(crate::ID, accounts, seeds) } pub fn marinade_withdraw_stake_verify_account_keys( accounts: MarinadeWithdrawStakeAccounts<'_, '_>, @@ -1062,6 +1199,10 @@ pub fn marinade_withdraw_stake_verify_account_keys( accounts.withdraw_stake_deposit_authority.key, &keys.withdraw_stake_deposit_authority, ), + (accounts.clock.key, &keys.clock), + (accounts.token_program.key, &keys.token_program), + (accounts.stake_program.key, &keys.stake_program), + (accounts.system_program.key, &keys.system_program), ] { if actual != expected { return Err((*actual, *expected)); @@ -1069,7 +1210,7 @@ pub fn marinade_withdraw_stake_verify_account_keys( } Ok(()) } -pub fn marinade_withdraw_stake_verify_account_privileges<'me, 'info>( +pub fn marinade_withdraw_stake_verify_writable_privileges<'me, 'info>( accounts: MarinadeWithdrawStakeAccounts<'me, 'info>, ) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { for should_be_writable in [ @@ -1085,3 +1226,9 @@ pub fn marinade_withdraw_stake_verify_account_privileges<'me, 'info>( } Ok(()) } +pub fn marinade_withdraw_stake_verify_account_privileges<'me, 'info>( + accounts: MarinadeWithdrawStakeAccounts<'me, 'info>, +) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> { + marinade_withdraw_stake_verify_writable_privileges(accounts)?; + Ok(()) +} diff --git a/stakedex_sdk/README.md b/stakedex_sdk/README.md index a2c4e5e..b29e88b 100644 --- a/stakedex_sdk/README.md +++ b/stakedex_sdk/README.md @@ -4,4 +4,4 @@ The main SDK crate. ## Test -`SOLANA_RPC_URL= cargo test -- --nocapture` \ No newline at end of file +`SOLANA_RPC_URL= cargo test -- --nocapture` diff --git a/stakedex_sdk/src/lib.rs b/stakedex_sdk/src/lib.rs index be05803..5293bb4 100644 --- a/stakedex_sdk/src/lib.rs +++ b/stakedex_sdk/src/lib.rs @@ -9,8 +9,8 @@ use solana_sdk::{ use spl_token::native_mint; pub use stakedex_interface::ID as stakedex_program_id; use stakedex_interface::{ - DepositStakeKeys, StakeWrappedSolIxArgs, StakeWrappedSolKeys, SwapViaStakeIxArgs, - SwapViaStakeKeys, + DepositStakeKeys, StakeWrappedSolIxArgs, StakeWrappedSolKeys, SwapViaStakeArgs, + SwapViaStakeIxArgs, SwapViaStakeKeys, }; use stakedex_lido::LidoStakedex; use stakedex_marinade::MarinadeStakedex; @@ -367,8 +367,10 @@ impl Stakedex { bridge_stake, }, SwapViaStakeIxArgs { - amount: swap_params.in_amount, - bridge_stake_seed, + args: SwapViaStakeArgs { + amount: swap_params.in_amount, + bridge_stake_seed, + }, }, )?; for mint_idx in [