From 5c07df078620e0810a098c7ba2a608070c71a3c0 Mon Sep 17 00:00:00 2001 From: Luis Covarrubias Date: Thu, 12 Feb 2026 14:24:24 -0800 Subject: [PATCH 1/2] fix(wasm-solana): don't add rent on top of staking amount The intent's amount already includes rent-exempt minimum. The WASM builder was double-counting by adding STAKE_ACCOUNT_RENT on top. BTC-3025 --- packages/wasm-solana/src/intent/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-solana/src/intent/build.rs b/packages/wasm-solana/src/intent/build.rs index 19d72a2..d2958e9 100644 --- a/packages/wasm-solana/src/intent/build.rs +++ b/packages/wasm-solana/src/intent/build.rs @@ -226,7 +226,7 @@ fn build_stake( system_ix::create_account( &fee_payer, &stake_pubkey, - amount + STAKE_ACCOUNT_RENT, + amount, STAKE_ACCOUNT_SPACE, &solana_stake_interface::program::ID, ), From d25b6cb5fe2e6d45006c5f280aa56423c3d0a955 Mon Sep 17 00:00:00 2001 From: Luis Covarrubias Date: Thu, 12 Feb 2026 14:28:04 -0800 Subject: [PATCH 2/2] feat(wasm-solana): add Native StakingType and make StakePoolConfig fields optional Add Native variant to StakingType enum so WASM can handle native staking intents that pass stakingType: "NATIVE". Make StakePoolConfig fields (reserveStake, managerFeeAccount, poolMint) optional since not all staking contexts provide every field. BTC-3025 --- packages/wasm-solana/src/intent/build.rs | 12 +++++++++++- packages/wasm-solana/src/intent/types.rs | 10 +++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/wasm-solana/src/intent/build.rs b/packages/wasm-solana/src/intent/build.rs index d2958e9..6dfb15a 100644 --- a/packages/wasm-solana/src/intent/build.rs +++ b/packages/wasm-solana/src/intent/build.rs @@ -300,6 +300,8 @@ fn build_jito_stake( .map_err(|_| WasmSolanaError::new("Invalid withdrawAuthority"))?; let reserve_stake: Pubkey = config .reserve_stake + .as_ref() + .ok_or_else(|| WasmSolanaError::new("Missing reserveStake"))? .parse() .map_err(|_| WasmSolanaError::new("Invalid reserveStake"))?; let destination_pool_account: Pubkey = config @@ -310,6 +312,8 @@ fn build_jito_stake( .map_err(|_| WasmSolanaError::new("Invalid destinationPoolAccount"))?; let manager_fee_account: Pubkey = config .manager_fee_account + .as_ref() + .ok_or_else(|| WasmSolanaError::new("Missing managerFeeAccount"))? .parse() .map_err(|_| WasmSolanaError::new("Invalid managerFeeAccount"))?; let referral_pool_account: Pubkey = config @@ -323,8 +327,10 @@ fn build_jito_stake( .map_err(|_| WasmSolanaError::new("Invalid referralPoolAccount"))?; let pool_mint: Pubkey = config .pool_mint + .as_ref() + .ok_or_else(|| WasmSolanaError::new("Missing poolMint"))? .parse() - .map_err(|_| WasmSolanaError::new(&format!("Invalid poolMint: {}", config.pool_mint)))?; + .map_err(|_| WasmSolanaError::new("Invalid poolMint"))?; // Build instruction data let instruction_data = StakePoolInstruction::DepositSol(amount); @@ -541,10 +547,14 @@ fn build_jito_unstake( .map_err(|_| WasmSolanaError::new("Invalid sourcePoolAccount"))?; let manager_fee_account: Pubkey = config .manager_fee_account + .as_ref() + .ok_or_else(|| WasmSolanaError::new("Missing managerFeeAccount"))? .parse() .map_err(|_| WasmSolanaError::new("Invalid managerFeeAccount"))?; let pool_mint: Pubkey = config .pool_mint + .as_ref() + .ok_or_else(|| WasmSolanaError::new("Missing poolMint"))? .parse() .map_err(|_| WasmSolanaError::new("Invalid poolMint"))?; diff --git a/packages/wasm-solana/src/intent/types.rs b/packages/wasm-solana/src/intent/types.rs index 9aa6a81..3729e4e 100644 --- a/packages/wasm-solana/src/intent/types.rs +++ b/packages/wasm-solana/src/intent/types.rs @@ -26,6 +26,7 @@ pub enum IntentType { #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum StakingType { + Native, Jito, Marinade, } @@ -189,13 +190,16 @@ pub struct StakePoolConfig { pub stake_pool_address: Option, #[serde(default)] pub withdraw_authority: Option, - pub reserve_stake: String, + #[serde(default)] + pub reserve_stake: Option, #[serde(default)] pub destination_pool_account: Option, - pub manager_fee_account: String, + #[serde(default)] + pub manager_fee_account: Option, #[serde(default)] pub referral_pool_account: Option, - pub pool_mint: String, + #[serde(default)] + pub pool_mint: Option, #[serde(default)] pub validator_list: Option, #[serde(default)]