Web3.js – Fixing Uncaught TypeError in web3.personal.sign Function with Truffle and Metamask

metamasktruffleweb3js

I'm running Metamask on Chrome.

When I run the following in the developer console on a random page or even Etherdelta Metamask prompts me to sign a message and this is the expected behaviour.

web3.personal.sign('0x68656c6c6f', web3.eth.accounts[0], console.log)

However, when I try to run the same in the dev console on the basic Dapp created by $ truffle init webpack I get an error saying:

Uncaught TypeError: web3.personal.sign is not a function

web3.personal does not have a function "sign" but has only ["_requestManager", "newAccount", "unlockAccount", "sendTransaction", "lockAccount", "listAccounts", "getListAccounts"] on the truffle dapp but has the following on other sites ["_requestManager", "newAccount", "importRawKey", "unlockAccount", "ecRecover", "sign", "sendTransaction", "lockAccount", "listAccounts", "getListAccounts"].

Note: web3.eth.sign(web3.eth.coinbase, '0x68656c6c6f', console.log) still works though.

Why is this happening?


Steps to reproduce the issue:

  1. Create the basic truffle dapp by running the following commands:

    • truffle init webpack
    • truffle compile
    • truffle migrate
    • npm run dev
  2. Open http://127.0.0.1:8081 in Chrome

  3. Run web3.personal.sign('0x68656c6c6f', web3.eth.accounts[0], console.log) in the dev console.

Best Answer

In Summary

Use web3.eth.sign() instead.

Why not web3.personal?

Despite web3.personal being defined in some implementations, it's not a standard as far as I can tell.

The v0 web3.js API does not list the personal API. Neither does the v1, except for web3.eth.personal, which may be what you want.

I believe Metamask is exposing the non-standard API web3.personal. (So is the web3 included in geth attach)

Update: Confirmation from Metamask

In response from metamask to my question, "Which spec did you base web3.personal on?"

kumavis commented 15 minutes ago

@carver et al
geth thread: ethereum/go-ethereum#2940
our implementation: https://github.com/metamask/eth-sig-util
usage examples: https://github.com/flyswatter/js-eth-personal-sign-example

This confirms my suspicion that web3.personal isn't a standard. Some clients are copying what other clients did. Which means you can't assume that it will be done the same way everywhere.

Web3.js v0 vs v1 in Truffle

Truffle's most recent release note that mentions web3.js is:

v3.4.6 ... Internal: We now use web3 v0.20.1 inside Truffle

So you'll have to make due with the v0 web3.js implementation of web3.eth.sign until they update to v1. V1 is still in beta, so it may not happen right away.

Related Topic