diff --git a/rust/main/chains/hyperlane-sealevel/src/interchain_security_module.rs b/rust/main/chains/hyperlane-sealevel/src/interchain_security_module.rs index aaf2683fd4..89023032dd 100644 --- a/rust/main/chains/hyperlane-sealevel/src/interchain_security_module.rs +++ b/rust/main/chains/hyperlane-sealevel/src/interchain_security_module.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use num_traits::cast::FromPrimitive; -use solana_sdk::{instruction::Instruction, pubkey::Pubkey, signature::Keypair}; +use solana_sdk::{instruction::Instruction, pubkey::Pubkey}; use tracing::warn; use hyperlane_core::{ @@ -10,19 +10,23 @@ use hyperlane_core::{ use hyperlane_sealevel_interchain_security_module_interface::InterchainSecurityModuleInstruction; use serializable_account_meta::SimulationReturnData; -use crate::{ConnectionConf, SealevelProvider, SealevelRpcClient}; +use crate::{ConnectionConf, SealevelKeypair, SealevelProvider, SealevelRpcClient}; /// A reference to an InterchainSecurityModule contract on some Sealevel chain #[derive(Debug)] pub struct SealevelInterchainSecurityModule { - payer: Option, + payer: Option, program_id: Pubkey, provider: SealevelProvider, } impl SealevelInterchainSecurityModule { /// Create a new sealevel InterchainSecurityModule - pub fn new(conf: &ConnectionConf, locator: ContractLocator, payer: Option) -> Self { + pub fn new( + conf: &ConnectionConf, + locator: ContractLocator, + payer: Option, + ) -> Self { let provider = SealevelProvider::new(locator.domain.clone(), conf); let program_id = Pubkey::from(<[u8; 32]>::from(locator.address)); Self { diff --git a/rust/main/chains/hyperlane-sealevel/src/keypair.rs b/rust/main/chains/hyperlane-sealevel/src/keypair.rs new file mode 100644 index 0000000000..7e778e09f0 --- /dev/null +++ b/rust/main/chains/hyperlane-sealevel/src/keypair.rs @@ -0,0 +1,52 @@ +use std::ops::Deref; + +use solana_sdk::{signature::Keypair, signer::Signer}; + +/// Wrapper around solana_sdk's Keypair. +/// This implements a custom Debug so the private keys are +/// not exposed. +pub struct SealevelKeypair(pub Keypair); + +impl SealevelKeypair { + /// create new SealevelKeypair + pub fn new(keypair: Keypair) -> Self { + Self(keypair) + } + /// Return the underlying keypair + pub fn keypair(&self) -> &Keypair { + &self.0 + } +} + +impl Deref for SealevelKeypair { + type Target = Keypair; + + /// Return the underlying keypair + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::fmt::Debug for SealevelKeypair { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.pubkey()) + } +} + +#[cfg(test)] +mod test { + use solana_sdk::signature::Keypair; + + use super::SealevelKeypair; + + #[test] + fn test_no_exposed_secret_key() { + let priv_key = "2ckDxzDFpZGeWd7VbHzd6dMgxYpqVDPA8XzeXFuuUJ1K8CjtyTBenD1TSPPovahXEFw3kBihoyAKktyro22MP4bN"; + let pub_key = "6oKnHXD2LRzQ4iNsgvkGSNNx68vj5GCYYpR2icy5JZhE"; + + let keypair = SealevelKeypair(Keypair::from_base58_string(priv_key)); + + let actual = format!("{:?}", keypair); + assert_eq!(pub_key, actual); + } +} diff --git a/rust/main/chains/hyperlane-sealevel/src/lib.rs b/rust/main/chains/hyperlane-sealevel/src/lib.rs index 6121bbe27f..5b014b067c 100644 --- a/rust/main/chains/hyperlane-sealevel/src/lib.rs +++ b/rust/main/chains/hyperlane-sealevel/src/lib.rs @@ -7,6 +7,7 @@ pub use crate::multisig_ism::*; pub use interchain_gas::*; pub use interchain_security_module::*; +pub use keypair::*; pub use mailbox::*; pub use merkle_tree_hook::*; pub use provider::*; @@ -19,6 +20,7 @@ mod account; mod error; mod interchain_gas; mod interchain_security_module; +mod keypair; mod log_meta_composer; mod mailbox; mod merkle_tree_hook; diff --git a/rust/main/chains/hyperlane-sealevel/src/mailbox.rs b/rust/main/chains/hyperlane-sealevel/src/mailbox.rs index a6098da254..cd653e4428 100644 --- a/rust/main/chains/hyperlane-sealevel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-sealevel/src/mailbox.rs @@ -29,7 +29,7 @@ use solana_sdk::{ commitment_config::CommitmentConfig, instruction::{AccountMeta, Instruction}, pubkey::Pubkey, - signer::{keypair::Keypair, Signer as _}, + signer::Signer as _, }; use tracing::{debug, info, instrument, warn}; @@ -40,14 +40,17 @@ use hyperlane_core::{ ReorgPeriod, SequenceAwareIndexer, TxCostEstimate, TxOutcome, H256, H512, U256, }; -use crate::log_meta_composer::{ - is_message_delivery_instruction, is_message_dispatch_instruction, LogMetaComposer, -}; use crate::tx_submitter::TransactionSubmitter; use crate::{ account::{search_accounts_by_discriminator, search_and_validate_account}, priority_fee::PriorityFeeOracle, }; +use crate::{ + log_meta_composer::{ + is_message_delivery_instruction, is_message_dispatch_instruction, LogMetaComposer, + }, + SealevelKeypair, +}; use crate::{ConnectionConf, SealevelProvider, SealevelRpcClient}; const SYSTEM_PROGRAM: &str = "11111111111111111111111111111111"; @@ -79,7 +82,7 @@ pub struct SealevelMailbox { inbox: (Pubkey, u8), pub(crate) outbox: (Pubkey, u8), pub(crate) provider: SealevelProvider, - payer: Option, + payer: Option, priority_fee_oracle: Box, tx_submitter: Box, } @@ -89,7 +92,7 @@ impl SealevelMailbox { pub fn new( conf: &ConnectionConf, locator: ContractLocator, - payer: Option, + payer: Option, ) -> ChainResult { let provider = SealevelProvider::new(locator.domain.clone(), conf); let program_id = Pubkey::from(<[u8; 32]>::from(locator.address)); @@ -379,7 +382,7 @@ impl SealevelMailbox { Ok(inbox) } - fn get_payer(&self) -> ChainResult<&Keypair> { + fn get_payer(&self) -> ChainResult<&SealevelKeypair> { self.payer .as_ref() .ok_or_else(|| ChainCommunicationError::SignerUnavailable) diff --git a/rust/main/chains/hyperlane-sealevel/src/multisig_ism.rs b/rust/main/chains/hyperlane-sealevel/src/multisig_ism.rs index a3cdb1273f..1396248fc6 100644 --- a/rust/main/chains/hyperlane-sealevel/src/multisig_ism.rs +++ b/rust/main/chains/hyperlane-sealevel/src/multisig_ism.rs @@ -8,10 +8,9 @@ use serializable_account_meta::SimulationReturnData; use solana_sdk::{ instruction::{AccountMeta, Instruction}, pubkey::Pubkey, - signature::Keypair, }; -use crate::{ConnectionConf, SealevelProvider, SealevelRpcClient}; +use crate::{ConnectionConf, SealevelKeypair, SealevelProvider, SealevelRpcClient}; use multisig_ism::interface::{ MultisigIsmInstruction, VALIDATORS_AND_THRESHOLD_ACCOUNT_METAS_PDA_SEEDS, @@ -20,7 +19,7 @@ use multisig_ism::interface::{ /// A reference to a MultisigIsm contract on some Sealevel chain #[derive(Debug)] pub struct SealevelMultisigIsm { - payer: Option, + payer: Option, program_id: Pubkey, domain: HyperlaneDomain, provider: SealevelProvider, @@ -28,7 +27,11 @@ pub struct SealevelMultisigIsm { impl SealevelMultisigIsm { /// Create a new Sealevel MultisigIsm. - pub fn new(conf: &ConnectionConf, locator: ContractLocator, payer: Option) -> Self { + pub fn new( + conf: &ConnectionConf, + locator: ContractLocator, + payer: Option, + ) -> Self { let provider = SealevelProvider::new(locator.domain.clone(), conf); let program_id = Pubkey::from(<[u8; 32]>::from(locator.address)); diff --git a/rust/main/chains/hyperlane-sealevel/src/rpc/client.rs b/rust/main/chains/hyperlane-sealevel/src/rpc/client.rs index 3e4a17ee85..11c3b18147 100644 --- a/rust/main/chains/hyperlane-sealevel/src/rpc/client.rs +++ b/rust/main/chains/hyperlane-sealevel/src/rpc/client.rs @@ -19,7 +19,7 @@ use solana_sdk::{ instruction::{AccountMeta, Instruction}, message::Message, pubkey::Pubkey, - signature::{Keypair, Signature, Signer}, + signature::{Signature, Signer}, transaction::Transaction, }; use solana_transaction_status::{ @@ -31,7 +31,7 @@ use hyperlane_core::{ChainCommunicationError, ChainResult, U256}; use crate::{ error::HyperlaneSealevelError, priority_fee::PriorityFeeOracle, - tx_submitter::TransactionSubmitter, + tx_submitter::TransactionSubmitter, SealevelKeypair, }; const COMPUTE_UNIT_MULTIPLIER_NUMERATOR: u32 = 11; @@ -74,7 +74,7 @@ impl SealevelRpcClient { /// Simulates an Instruction that will return a list of AccountMetas. pub async fn get_account_metas( &self, - payer: &Keypair, + payer: &SealevelKeypair, instruction: Instruction, ) -> ChainResult> { // If there's no data at all, default to an empty vec. @@ -302,7 +302,7 @@ impl SealevelRpcClient { /// an Err is returned. pub async fn simulate_instruction( &self, - payer: &Keypair, + payer: &SealevelKeypair, instruction: Instruction, ) -> ChainResult> { let commitment = CommitmentConfig::finalized(); @@ -357,7 +357,7 @@ impl SealevelRpcClient { pub async fn get_estimated_costs_for_instruction( &self, instruction: Instruction, - payer: &Keypair, + payer: &SealevelKeypair, tx_submitter: &dyn TransactionSubmitter, priority_fee_oracle: &dyn PriorityFeeOracle, ) -> ChainResult { @@ -440,7 +440,7 @@ impl SealevelRpcClient { pub async fn build_estimated_tx_for_instruction( &self, instruction: Instruction, - payer: &Keypair, + payer: &SealevelKeypair, tx_submitter: &dyn TransactionSubmitter, priority_fee_oracle: &dyn PriorityFeeOracle, ) -> ChainResult { @@ -485,7 +485,7 @@ impl SealevelRpcClient { compute_unit_limit: u32, compute_unit_price_micro_lamports: u64, instruction: Instruction, - payer: &Keypair, + payer: &SealevelKeypair, tx_submitter: &dyn TransactionSubmitter, sign: bool, ) -> ChainResult { @@ -513,7 +513,7 @@ impl SealevelRpcClient { Transaction::new_signed_with_payer( &instructions, Some(&payer.pubkey()), - &[payer], + &[payer.keypair()], recent_blockhash, ) } else { diff --git a/rust/main/hyperlane-base/src/settings/chains.rs b/rust/main/hyperlane-base/src/settings/chains.rs index 33600418bb..f50f6ddea0 100644 --- a/rust/main/hyperlane-base/src/settings/chains.rs +++ b/rust/main/hyperlane-base/src/settings/chains.rs @@ -240,9 +240,13 @@ impl ChainConf { } ChainConnectionConf::Sealevel(conf) => { let keypair = self.sealevel_signer().await.context(ctx)?; - h_sealevel::SealevelMailbox::new(conf, locator, keypair) - .map(|m| Box::new(m) as Box) - .map_err(Into::into) + h_sealevel::SealevelMailbox::new( + conf, + locator, + keypair.map(h_sealevel::SealevelKeypair::new), + ) + .map(|m| Box::new(m) as Box) + .map_err(Into::into) } ChainConnectionConf::Cosmos(conf) => { let signer = self.cosmos_signer().await.context(ctx)?; @@ -568,7 +572,9 @@ impl ChainConf { ChainConnectionConf::Sealevel(conf) => { let keypair = self.sealevel_signer().await.context(ctx)?; let ism = Box::new(h_sealevel::SealevelInterchainSecurityModule::new( - conf, locator, keypair, + conf, + locator, + keypair.map(h_sealevel::SealevelKeypair::new), )); Ok(ism as Box) } @@ -601,7 +607,11 @@ impl ChainConf { ChainConnectionConf::Fuel(_) => todo!(), ChainConnectionConf::Sealevel(conf) => { let keypair = self.sealevel_signer().await.context(ctx)?; - let ism = Box::new(h_sealevel::SealevelMultisigIsm::new(conf, locator, keypair)); + let ism = Box::new(h_sealevel::SealevelMultisigIsm::new( + conf, + locator, + keypair.map(h_sealevel::SealevelKeypair::new), + )); Ok(ism as Box) } ChainConnectionConf::Cosmos(conf) => {