I am using the following code to sign a message:

    jsonrpc: '2.0',
    id: 1,
    method: 'personal_sign',
    params: [
      `My account is ${this.accounts[0]}`,
  (err, res) => {
     // send res.result to server

on the server i do the following:

// Recover the public key
const candidate = web3.eth.accounts.recover(`My account is ${account}`, signature);

// Verify the recovered key and the key making the request are the same
return ethUtil.toChecksumAddress(candidate) === ethUtil.toChecksumAddress(myPublicKey)

This works correctly when using MetaMask, but the recovered address does not match when using Opera on android. From what I can tell both are using v0.20.7 of web3. Anyone have any ideas?

  • does it work if you use web3.personal.sign?
    – haxerl
    Aug 20, 2019 at 9:32
  • Unfortunately I get the error that personal sign is not supported @haxerl
    – pizzarob
    Aug 21, 2019 at 14:53
  • does it work when you change personal_sign to eth_sign or maybe try use send instead of sendAsync? and btw i though they have deprecated sendAsync function which resources did you read?
    – haxerl
    Aug 22, 2019 at 4:47
  • can you provide signed messages for both ? or transactions we can take the message from ? Aug 24, 2019 at 1:51

1 Answer 1


When using MetaMask you have a different public/private key.

Therefore another value gets returned.

  • I don't expect the values to be the same. I expect that web3.eth.accounts.recover gives me the correct address when recovering the signed message. However, when signing a message with Opera the address does not match that of the signing address when using the web3.eth.accounts.recover method
    – pizzarob
    Oct 6, 2019 at 23:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.