Skip to content

Commit 98e5aad

Browse files
committed
untested stuff that i've used in gotland wallet app
1 parent 0aad3c8 commit 98e5aad

File tree

2 files changed

+466
-54
lines changed

2 files changed

+466
-54
lines changed

src/signer.rs

+68-27
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,79 @@ pub struct LocalSigner {
126126
pub private_key_hex: String,
127127
}
128128

129+
// Manual implementation of Serialize for LocalSigner
130+
impl Serialize for LocalSigner {
131+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
132+
where
133+
S: serde::Serializer,
134+
{
135+
use serde::ser::SerializeStruct;
136+
137+
// Serialize only the fields we need
138+
let mut state = serializer.serialize_struct("LocalSigner", 3)?;
139+
state.serialize_field("address", &self.address)?;
140+
state.serialize_field("chain_id", &self.chain_id)?;
141+
state.serialize_field("private_key_hex", &self.private_key_hex)?;
142+
state.end()
143+
}
144+
}
145+
146+
// Manual implementation of Deserialize for LocalSigner
147+
impl<'de> Deserialize<'de> for LocalSigner {
148+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
149+
where
150+
D: serde::Deserializer<'de>,
151+
{
152+
#[derive(Deserialize)]
153+
struct LocalSignerData {
154+
address: EthAddress,
155+
chain_id: u64,
156+
private_key_hex: String,
157+
}
158+
159+
let data = LocalSignerData::deserialize(deserializer)?;
160+
161+
// Reconstruct the LocalSigner from the private key
162+
match LocalSigner::from_private_key(&data.private_key_hex, data.chain_id) {
163+
Ok(signer) => Ok(signer),
164+
Err(e) => Err(serde::de::Error::custom(format!("Failed to reconstruct signer: {}", e))),
165+
}
166+
}
167+
}
168+
129169
impl LocalSigner {
130170
/// Create a new signer with a randomly generated private key
131171
pub fn new_random(chain_id: u64) -> Result<Self, SignerError> {
132-
// Generate a secure random private key
133-
let inner = PrivateKeySigner::random();
172+
// Generate a secure random private key directly
173+
let mut rng = thread_rng();
174+
let mut private_key_bytes = [0u8; 32];
175+
rng.fill_bytes(&mut private_key_bytes);
134176

135-
let address = inner.address();
177+
// Make sure the private key is valid (less than curve order)
178+
// TODO: This is a simplification
179+
let max_scalar = hex::decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140")
180+
.map_err(|_| SignerError::RandomGenerationError("Failed to decode max scalar".to_string()))?;
181+
182+
// Simple check: if our random bytes are >= max_scalar, regenerate
183+
// This is a simplified approach - production code would use more sophisticated comparison
184+
if private_key_bytes.as_slice().cmp(max_scalar.as_slice()) != std::cmp::Ordering::Less {
185+
// Try again with a new random value
186+
rng.fill_bytes(&mut private_key_bytes);
187+
}
136188

137-
// Extract the private key for storage
138-
let private_key_hex = Self::extract_private_key(&inner)?;
189+
// Convert to B256 for the PrivateKeySigner
190+
let key = B256::from_slice(&private_key_bytes);
191+
192+
// Store the private key hex string for later use
193+
let private_key_hex = format!("0x{}", hex::encode(private_key_bytes));
194+
195+
// Create the PrivateKeySigner
196+
let inner = match PrivateKeySigner::from_bytes(&key) {
197+
Ok(signer) => signer,
198+
Err(e) => return Err(SignerError::InvalidPrivateKey(e.to_string())),
199+
};
200+
201+
let address = inner.address();
139202

140203
Ok(Self {
141204
inner,
@@ -190,28 +253,6 @@ impl LocalSigner {
190253
})
191254
}
192255

193-
// jank
194-
/// Extract the private key hex string from an Alloy PrivateKeySigner
195-
fn extract_private_key(wallet: &PrivateKeySigner) -> Result<String, SignerError> {
196-
// This is a placeholder implementation until we find a better way to extract
197-
// the private key from PrivateKeySigner
198-
let debug_str = format!("{:?}", wallet);
199-
200-
// Parse the private key from the debug output
201-
let start_marker = "private_key: PrivateKey(";
202-
let end_marker = ")";
203-
204-
if let Some(start_idx) = debug_str.find(start_marker) {
205-
let key_start = start_idx + start_marker.len();
206-
if let Some(end_idx) = debug_str[key_start..].find(end_marker) {
207-
let key_hex = &debug_str[key_start..key_start + end_idx];
208-
return Ok(format!("0x{}", key_hex.trim_start_matches("0x")));
209-
}
210-
}
211-
212-
Err(SignerError::InvalidPrivateKey("Failed to extract private key".into()))
213-
}
214-
215256
/// Encrypt this signer using a password
216257
pub fn encrypt(&self, password: &str) -> Result<EncryptedSignerData, SignerError> {
217258
// Extract the private key hex (without 0x prefix)

0 commit comments

Comments
 (0)