diff --git a/signers/src/eth_signer/json_rpc_signer.rs b/signers/src/eth_signer/json_rpc_signer.rs index 04bc0b9d..9bb75edf 100755 --- a/signers/src/eth_signer/json_rpc_signer.rs +++ b/signers/src/eth_signer/json_rpc_signer.rs @@ -1,5 +1,6 @@ use crate::eth_signer::{EthSignerError, PackedEthSignature}; use crate::RpcErr; +use hex; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; @@ -39,11 +40,32 @@ impl JsonRpcSigner { self.provider.selectedAddress() } + // https://docs.metamask.io/wallet/reference/provider-api/#legacy-properties + // https://docs.metamask.io/whats-new/#march-2024 + // selectedAddress is deprecated and not all wallet extensions provide this method, use eth_requestAccounts instead + pub async fn get_request_account(&self) -> Result { + let req_params = RequestArguments { + method: "eth_requestAccounts".to_string(), + params: Vec::new(), + }; + let params = serde_wasm_bindgen::to_value(&req_params) + .map_err(|e| EthSignerError::CustomError(e.to_string()))?; + let address = self.provider.request(params).await.map_err(|e| { + EthSignerError::RpcSignError(serde_wasm_bindgen::from_value::(e).unwrap()) + })?; + let address = serde_wasm_bindgen::from_value::>(address) + .map_err(|e| EthSignerError::SigningFailed(e.to_string()))?; + Ok(address[0].clone()) + } + pub async fn sign_message(&self, message: &[u8]) -> Result { - let provider_address = self.provider.selectedAddress(); + let provider_address = self.get_request_account().await?; let mut params = Vec::new(); - let msg_str = - std::str::from_utf8(message).map_err(|e| EthSignerError::CustomError(e.to_string()))?; + + // https://docs.metamask.io/wallet/reference/personal_sign/ + // Convert message to hex string since non-hex string are not well supported by all wallet extensions, result signature should be the same. + let msg_str = format! { "0x{}", hex::encode(message) }; + params.push(serde_json::to_value(msg_str).unwrap()); params.push(serde_json::to_value(provider_address).unwrap()); let req_params = RequestArguments { @@ -64,7 +86,7 @@ impl JsonRpcSigner { &self, message: &[u8], ) -> Result { - let provider_address = self.provider.selectedAddress(); + let provider_address = self.get_request_account().await?; let mut params = Vec::new(); let msg_str = std::str::from_utf8(message).map_err(|e| EthSignerError::CustomError(e.to_string()))?;