Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wallet.SignMessage failing without catchable error #491

Closed
RyRy79261 opened this issue Apr 16, 2019 · 11 comments
Closed

wallet.SignMessage failing without catchable error #491

RyRy79261 opened this issue Apr 16, 2019 · 11 comments
Labels
discussion Questions, feedback and general information.

Comments

@RyRy79261
Copy link

Description

When attempting to sign a message in Coinbase, Status & Cipher, wallet.signMessage throws without error crashing the parent function.

All EIP 1102 set up, providers, web3 & wallet all available and meta functions executing as expected, all user interaction based functions crash without throwing an error to investigate

@mrwillis
Copy link

mrwillis commented Apr 16, 2019

I had this exact issue. wallet.signMessage actually uses eth_sign under the hood and personal_sign for MetaMask. So it actually silently works for MM :)

However, it doesn't handle other wallets. Likely the case is that those wallets do not support proper eth_sign behaviour, causing the issue. Recommendation is to do

signer.provider.send("personal_sign", [param, param]) instead for those wallets

That should fix the issue, however if you are signing a UTF-8 string, keep in mind you will have to do the decoding yourself to hex since you're calling the raw method.

signMessage(message: Arrayish | string): Promise<string> {

@ricmoo maybe there is a better solution for handling these other wallets? It is bizarre that these wallets do not support proper eth_sign behaviour as it is in the spec.

@RyRy79261
Copy link
Author

Thanks @mrwillis I tried your example however I still did not get any results.

I am signing message that was signed by another wallet.

Attempt 1: No error fail

      signer.provider.send("personal_sign", [message])

Attempt 2: no error fail

      signer.provider.send("personal_sign", [message, signerAddress])

Attempt 3 : e.toLowerCase is not a function

      await signer.provider.send("personal_sign", [message, signerAddress])

Attempt 4: directly sending the tx

 let final = await new Promise((resolve,reject)=>{
      let result = web3.currentProvider.sendAsync({
        jsonrpc: '2.0',
        id: 1,
        method: 'personal_sign',
        params: [
          message, // message
          signerAddress // address
        ]
        }, (err, res) => {
          console.log(err, res)
          resolve(res)
        })
    })
    debugger;
    return final

@mrwillis
Copy link

mrwillis commented Apr 16, 2019

I believe the order is incorrect here. You need to put the address first in the params aray.

@mrwillis
Copy link

mrwillis commented Apr 16, 2019

Also try address.toLowerCase().

Code for personal_sign for MM in signMessage. You basically need to replicate this.

if (method == 'eth_sign' && this._web3Provider.isMetaMask) {

@RyRy79261
Copy link
Author

Thanks @mrwillis I got it working after recasting some variables however oddly enough now when using verify message it returns the incorrect account.

I've tried changing the network id, using ethers.utils.hashMessage on the message, the address in lower case and normal case.

I'm trying out all the signing functions in the web3, wallet, web3.personal, web3.eth objects but its not lining up.

Essentially I'm signing the message then verifying from the same device, immediately so theres nothing happening inbetween the signing and verification in the my code.

@BigMurry
Copy link

In ethers.js signing message you can always use: (tested in coinbase wallet, imToken, opera, metamask, status wallet)

const data = ethers.utils.toUtf8Bytes('some txt message');
const signer = provider.getSigner();
const addr = await signer.getAddress();
const sig = await provider.send('personal_sign', [ethers.utils.hexlify(data), addr.toLowerCase()]);

@RyRy79261
Copy link
Author

@BigMurry That solved it on all my browsers, thank you! :D

@ricmoo
Copy link
Member

ricmoo commented Apr 18, 2019

The order for eth_sign vs personal_signMessage are flipped, and in MetaMask, the order can be either (with some incredibly weird and ambiguous edge cases).

Does using eth_sign on nodes that prefer the personal_ variant throw anything? I can do what I do for eth_chainId, which is to fallback onto net_version if it returns an error.

@ricmoo ricmoo added discussion Questions, feedback and general information. investigate Under investigation and may be a bug. labels Apr 18, 2019
RyRy79261 added a commit to ProteaNetwork/protea-gather that referenced this issue May 31, 2019
@ricmoo
Copy link
Member

ricmoo commented Jun 3, 2020

I think this was resolved? I'm going to close this now, but if not, please feel free to re-open.

Thanks! :)

@ricmoo ricmoo closed this as completed Jun 3, 2020
@EvilJordan
Copy link

@BigMurry You the man for this. Happy Holidays!

@luannv1203
Copy link

In ethers.js signing message you can always use: (tested in coinbase wallet, imToken, opera, metamask, status wallet)

const data = ethers.utils.toUtf8Bytes('some txt message');
const signer = provider.getSigner();
const addr = await signer.getAddress();
const sig = await provider.send('personal_sign', [ethers.utils.hexlify(data), addr.toLowerCase()]);

@BigMurry it not working with my browser
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Questions, feedback and general information.
Projects
None yet
Development

No branches or pull requests

6 participants