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

Sign and verify personal message via Metamask #17

Closed
cryptobys-rami opened this issue Nov 2, 2021 · 4 comments
Closed

Sign and verify personal message via Metamask #17

cryptobys-rami opened this issue Nov 2, 2021 · 4 comments

Comments

@cryptobys-rami
Copy link

First of all thanks v much for this library!

Is your feature request related to a problem? Please describe.
Feature request to help verifying that a user owns a certain wallet

Describe the solution you'd like
I would like to know if its possible to sign a Metamask personal message which can then be verified server side in order to link off chain user accounts with Wallets. Ideally i would like it to make a signature which does not trigger the Metamask 'card blanche' warning below.

ED323FE7-030F-42F4-A9E3-E45510B4DA3A_4_5005_c

@y-pakorn
Copy link
Owner

y-pakorn commented Nov 2, 2021

Thank you!

If you’re referring to manually signing the message, the package already has the functionality to do that.

Please look for the signMessage method on Signer class. (Accessible by using ‘getSigner’ in Provider class.) And to verify the message, please use EthUtils.verifyMessage method.

About the warning message, I'm pretty sure It's from the wallet part, and it would be impossible to suppress that from the package.

I hope you understand the risk of manually signing the message as well.

This is a simple example of how to implement that.

final sig = await provider!.getSigner().signMessage('hehe');
final acc = EthUtils.verifyMessage('hehe', sig);
print(acc);

@cryptobys-rami
Copy link
Author

cryptobys-rami commented Nov 2, 2021

Thank you very much for your prompt response.

I am referring to the 'personal.sign' spec (ethereum/go-ethereum#2940), an example of which is here: https://medium.com/hackernoon/writing-for-blockchain-wallet-signature-request-messages-6ede721160d5

where this web3 code snippet:

handleSignMessage = ({ publicAddress, nonce }) => {
    return new Promise((resolve, reject) =>
      web3.personal.sign(
        web3.fromUtf8(`I am signing my one-time nonce: ${nonce}`),
        publicAddress,
        (err, signature) => {
          if (err) return reject(err);
          return resolve({ publicAddress, signature });
        }
      )
    );
  };

Seems to result in a warning-free Metamask notification - which makes sense because it is prefixed with some text that makes it impossible to sign transactions with the same signature.

The purpose of personal sign is to avoid open ended signatures. Reference below from Metamask docs:

https://docs.metamask.io/guide/signing-data.html#a-brief-history

In particular, the method eth_sign is an open-ended signing method that allows signing an arbitrary hash, which means it can be used to sign transactions, or any other data, making it a dangerous phishing risk.

For this reason, we make this method show the most frightening possible message to the user, and generally discourage using this method in production. However, some applications (usually admin panels internal to teams) use this method for the sake of its ease of use, and so we have continued to support it for the sake of not breaking the workflows of active projects.

Eventually, the personal_sign spec (opens new window)was proposed, which added a prefix to the data so it could not impersonate transactions. We also made this method able to display human readable text when UTF-8 encoded, making it a popular choice for site logins.

This would be very useful as it would allow users to verify their wallet with a site, with minimal security risk, and no need for smart contract interaction (which costs money).

Thanks very much.

@y-pakorn
Copy link
Owner

y-pakorn commented Nov 2, 2021

Yes, signMessage in ethers is prob personal_sign in ethereum. I tested and there's no warning.

If you want to sign a transaction, use signTransaction instead.

@cryptobys-rami
Copy link
Author

Image 02-11-2021 at 12 08

I can confirm this works! Nice work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants