#StackBounty: #web3js #metamask #javascript #web3js-v1.x How Can You Find the Ethereum Provider on Web3 Browsers Other Than MetaMask?

Bounty: 50

MetaMask provides the following way currently to find a provider for their upcoming 2020 breaking change:

// Running on the page, in the browser
// This API will go live in Q1 2020
// It will be the only API available after a 6-week deprecation period

if (!ethereum || !ethereum.isMetaMask) {
  throw new Error('Please install MetaMask.')
}

/*********************************************************/
/* Handle chain (network) and chainChanged, per EIP 1193 */
/*********************************************************/

let currentChainId = null
ethereum.send('eth_chainId')
  .then(handleChainChanged)
  .catch(err => console.error(err)) // This should never happen

ethereum.on('chainChanged', handleChainChanged)

function handleChainChanged (chainId) {

  if (currentChainId !== chainId) {

    currentChainId = chainId
    // Run any other necessary logic...
  }
}

/**********************************************************/
/* Handle user accounts and accountsChanged, per EIP 1193 */
/**********************************************************/

let currentAccount = null
ethereum.send('eth_accounts')
  .then(handleAccountsChanged)
  .catch(err => {
    // In the future, maybe in 2020, this will return a 4100 error if
    // the user has yet to connect
    if (err.code === 4100) { // EIP 1193 unauthorized error
      console.log('Please connect to MetaMask.')
    } else {
      console.error(err)
    }
  })

// Note that this event is emitted on page load.
// If the array of accounts is non-empty, you're already
// connected.
ethereum.on('accountsChanged', handleAccountsChanged)

// For now, 'eth_accounts' will continue to always return an array
function handleAccountsChanged (accounts) {

  if (accounts.length === 0) {

    // MetaMask is locked or the user has not connected any accounts
    console.log('Please connect to MetaMask.')

  } else if (accounts[0] !== currentAccount) {

    currentAccount = accounts[0]
    // Run any other necessary logic...
  }
}

/***********************************/
/* Handle connecting, per EIP 1102 */
/***********************************/

// You should only attempt to connect in response to user interaction,
// such as a button click. Otherwise, you're popup-spamming the user
// like it's 1999.
// If you can't retrieve the user's account(s), you should encourage the user
// to initiate a connection attempt.
document.getElementById('connectButton', connect)

function connect () {

  // This is equivalent to ethereum.enable()
  ethereum.send('eth_requestAccounts')
    .then(handleAccountsChanged)
    .catch(err => {
      if (err.code === 4001) { // EIP 1193 userRejectedRequest error
        console.log('Please connect to MetaMask.')
      } else {
        console.error(err)
      }
    })
}

I am struggling to get my frontend to recognize a web3.js provider that is not MetaMask. The above code works perfectly with the current version of MetaMask, but does not work in any other Web3 browsers. If I inject my own web3.js, I get Can't find variable: Web3 and Can't find variable: ethereum MetaMask’s documentation is highly confusing, especially in light of the fact that it still injects v0.2 of web3.js while forcing you soon to completely change the way you find a provider. I don’t even know which version of web3.js the above code is for, 1.2 or 2.0. It is all unclear from all their convoluted press releases and blogs that seem to come from a different person on the team.

How can I make the above code work for other web3.js browsers like Cipher or Parity?

Currently I do this with v0.2:

if (typeof web3 !== 'undefined') {
    console.log('Web3 Detected! ' + web3.currentProvider.constructor.name)
    window.web3 = new Web3(web3.currentProvider);
    web3.eth.defaultAccount = web3.eth.accounts[0];
} else {
    console.log('No Web3 Detected, Using HTTP Provider')
    web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io/v3/xxxxxxx"));
    alert("You are not logged into a Web 3.0 enabled wallet such as MetaMask. You will be able to see the current status of the contract via Infura Web 3.0 services, but you will not be able to interact with the Dapp. Please login to a Web 3.0 wallet and refresh the page to use all functions.");
}


Get this bounty!!!

#StackBounty: #web3js #metamask signed message different on opera and metamask

Bounty: 50

I am using the following code to sign a message:

web3.currentProvider.sendAsync(
  {
    jsonrpc: '2.0',
    id: 1,
    method: 'personal_sign',
    params: [
      `My account is ${this.accounts[0]}`,
      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?


Get this bounty!!!