use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
#[cfg(feature = "native-auth")]
use solana_keypair::Keypair;
pub trait ExternalSigner: Send + Sync {
fn sign_message<'a>(
&'a self,
message: &'a [u8],
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, String>> + 'a>>;
fn sign_transaction<'a>(
&'a self,
tx_bytes: &'a [u8],
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, String>> + 'a>>;
}
pub enum SigningStrategy {
#[cfg(feature = "native-auth")]
Native(Arc<Keypair>),
WalletAdapter(Arc<dyn ExternalSigner>),
Privy { wallet_id: String },
}
pub(crate) fn classify_signer_error(error: String) -> crate::error::SdkError {
let lower = error.to_lowercase();
let is_cancellation = lower.contains("reject")
|| lower.contains("cancel")
|| lower.contains("denied")
|| lower.contains("user refused")
|| lower.contains("declined")
|| lower.contains("reflect.get called on non-object");
if is_cancellation {
crate::error::SdkError::UserCancelled
} else {
crate::error::SdkError::Signing(error)
}
}
impl Clone for SigningStrategy {
fn clone(&self) -> Self {
match self {
#[cfg(feature = "native-auth")]
Self::Native(keypair) => Self::Native(keypair.clone()),
Self::WalletAdapter(signer) => Self::WalletAdapter(signer.clone()),
Self::Privy { wallet_id } => Self::Privy {
wallet_id: wallet_id.clone(),
},
}
}
}