superblocks-lab
superblocks-lab copied to clipboard
Downloaded dapp calling eth accounts won't work (Pizza)
Environment/Browser
1.6.1. Still valid on version 1.7.0
Description
Downloaded Pizza template Dapp won't work. This appears to be related to the missing enable call to MetaMask, to allow accessing injected MetaMask accounts.
Steps to reproduce
- Create a new project from the CryptoPizza template
- Set Ropsten network (in Select a Network button) or any other external network
- Deploy CryptoPizza.sol
- Open Preview panel
- Click Download DApp button
- Run the downloaded html file locally
- Observe Browser Console error
Expected result
Expected it to work just like Preview.
Actual result
jquery.js:3827 Uncaught TypeError: Cannot read property 'eth' of undefined
Line is: window.web3.eth.accounts[0]
.
Related
- See also:
environmentUpdateEpic
- Issue #391
The same might apply to other templates. Also observed when running a local download copy of ERC-20 Token template.
Problem
In order to retrieve account information when using _MetaMask, it is now required to ask for user's consent before direct access to the account is granted.
See also: ethereum.enable()
and https://medium.com/metamask/https-medium-com-metamask-breaking-change-injecting-web3-7722797916a8
The program propagates the empty account address and fails to call getBalance
and related operations.
Possible solution
Add the MetaMask authorization request pop-up with the enable()
call. That will provide valid accounts data this.web3.eth.accounts[0]
, but only after user's consent.
Example with ERC-20 token template
Change MyToken.init
to become an async
function and add the new MetaMask code (from the referenced blog post) after the this.web3
assignment in that same function.
Example:
MyToken.prototype.init = async function(cb) {
this.web3 = new Web3(
(window.web3 && window.web3.currentProvider) ||
new Web3.providers.HttpProvider(this.Contract.endpoint));
if (window.ethereum) {
window.web3 = new Web3(ethereum);
try {
await ethereum.enable();
console.log('Accounts are now accessible!');
} catch (error) {
console.error(error);
}
} else if (window.web3) {
window.web3 = new Web3(web3.currentProvider);
console.log('Accounts are already accessible!');
} else {
console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
}
[...]
}
Extra notes
In order to get MetaMask notification to appear, it is required that the dapp file is served by a web server. In case the dapp is accessed via file:///...
, calls to window.web3
or window.ethereum
won't work.