MetaMask / metamask-snaps-beta

Fork of MetaMask that supports plugins! Read the Wiki!
https://github.com/MetaMask/metamask-snaps-beta/wiki
MIT License
144 stars 57 forks source link

Strange behavior with `ethers.js` #96

Closed jazzandrock closed 5 years ago

jazzandrock commented 5 years ago

Describe the bug When I execute these lines in a plugin:

const ethers = require('ethers')

let provider = new ethers.providers.Web3Provider(wallet)
let signer = provider.getSigner()
let signature = await signer.signMessage('login')
console.log('signature', signature);

A prompt opens, as usual, to confirm signing, but instead of "Message: login" it says "Message: 0x4d6174746572", which is login but hex encoded. Moreover, if I click 'sign', the prompt disappears, but signer.signMessage still never awaits.

To Reproduce Steps to reproduce the behavior:

  1. Open bls-signer in mm-plugin and paste these lines in indes.js:
const ethers = require('ethers')

async function test() {
  let provider = new ethers.providers.Web3Provider(wallet)
  let signer = provider.getSigner()
  console.log('We are about to get signature.');
  let signature = await signer.signMessage('login')
  console.log('Got signature', signature)
  return signature
}

Then, in registerRpcMessageHandler method in the same file, replace case 'signMessage': with:

case 'signMessage':
  return await test()

Also, add "eth_accounts" to "initialPermissions" in package.json.

  1. Launch the example as described here
  2. Click 'Sign Message', then 'Sign' in Signature request MetaMask prompt
  3. If you open the console of MetaMask (chrome://extensions/ => background page), you will see that signMessage never awaited.

Expected behavior Signature request prompt appears with message: login, after clicking sign, a 'Got signature' log appears in console.

Browser details (please complete the following information):

Additional context Also, when I execute the same lines in a browser (not in a plugin), an exception is thrown, saying I'm Unauthorized to perform action. In the stable version of MetaMask these lines work just fine. Is it a bug?

danfinlay commented 5 years ago

instead of "Message: login" it says "Message: 0x4d6174746572", which is login but hex encoded.

This is the normal behavior of the eth_sign method, which appears to be called by ethersSigner.signMessage().

If you want a human-readable string, you can use any of the other methods. personal_sign is the easiest, but signTypedData_v4 is the best for consuming on-chain.

Furthermore, since you're in a plugin context, you have access to your own deterministic private key, so you don't need user permission to use that one! const yourAppKey = wallet.getAppKey()!

Refer to our signing documentation for more info.

danfinlay commented 5 years ago

Well, we've reproduced. It does seem the dapp call is hitting personal_sign and the internal call is hitting eth_sign, we'll be investigating this.

danfinlay commented 5 years ago

In the meanwhile, I'll just re-emphasize:

since you're in a plugin context, you have access to your own deterministic private key, so you don't need user permission to use that one! const yourAppKey = wallet.getAppKey()!

This allows:

const signer = new ethers.Wallet(wallet.getAppKey());
rekmarks commented 5 years ago

This was related to different providers being injected into dapps vs plugins. The plugin provider is now a strict superset of the dapp provider, and I've confirmed that ether's signer.signMessage('login') works the same in both.

@jazzandrock, thank you again for bringing this to our attention, and let us know if you have any other problems.