starknet_rust_signers/
local_wallet.rs

1use crate::{Infallible, Signer, SignerInteractivityContext, SigningKey, VerifyingKey};
2
3use async_trait::async_trait;
4use starknet_rust_core::{
5    crypto::{EcdsaSignError, Signature},
6    types::Felt,
7};
8
9/// A signer that simply holds the signing (private) key in memory for performing cryptographic
10/// operations. It's recommended to use hardware-based signers for use cases involving real value.
11#[derive(Debug, Clone)]
12pub struct LocalWallet {
13    private_key: SigningKey,
14}
15
16/// Errors using [`LocalWallet`].
17#[derive(Debug, thiserror::Error)]
18pub enum SignError {
19    /// ECDSA signature error.
20    #[error(transparent)]
21    EcdsaSignError(EcdsaSignError),
22}
23
24impl LocalWallet {
25    /// Constructs [`LocalWallet`] from a [`SigningKey`].
26    pub fn from_signing_key(key: SigningKey) -> Self {
27        key.into()
28    }
29}
30
31#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
32#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
33impl Signer for LocalWallet {
34    type GetPublicKeyError = Infallible;
35    type SignError = SignError;
36
37    async fn get_public_key(&self) -> Result<VerifyingKey, Self::GetPublicKeyError> {
38        Ok(self.private_key.verifying_key())
39    }
40
41    async fn sign_hash(&self, hash: &Felt) -> Result<Signature, Self::SignError> {
42        Ok(self.private_key.sign(hash)?)
43    }
44
45    fn is_interactive(&self, _context: SignerInteractivityContext<'_>) -> bool {
46        false
47    }
48}
49
50impl From<SigningKey> for LocalWallet {
51    fn from(value: SigningKey) -> Self {
52        Self { private_key: value }
53    }
54}
55
56impl From<EcdsaSignError> for SignError {
57    fn from(value: EcdsaSignError) -> Self {
58        Self::EcdsaSignError(value)
59    }
60}