diff --git a/app/assets/onepager/js/web3alert.js b/app/assets/onepager/js/web3alert.js index 6c8db47281e..ec9009e7ca2 100644 --- a/app/assets/onepager/js/web3alert.js +++ b/app/assets/onepager/js/web3alert.js @@ -29,6 +29,8 @@ var metaMaskWarning = function() { _alert({ message: gettext('You must install Metamask to use this tool.') }, 'info'); } return true; + } else if (is_metamask_unlocked && !is_metamask_approved) { + _alert({ message: gettext('Please connect to Metamask.') }, 'info'); } else if (web3.eth.accounts.length == 0) { _alert({ message: gettext('Please unlock Metamask.') }, 'info'); return true; diff --git a/app/assets/v2/css/buttons.css b/app/assets/v2/css/buttons.css index 07b0e5ce9c5..7743323242e 100644 --- a/app/assets/v2/css/buttons.css +++ b/app/assets/v2/css/buttons.css @@ -187,3 +187,10 @@ button:focus { .btn > svg:first-child { margin-right: .5rem; } + +#metamask_connect { + background: none; + color: white; + border: 2px solid white; + border-radius: 10px; +} diff --git a/app/assets/v2/js/metamask-approval.js b/app/assets/v2/js/metamask-approval.js new file mode 100644 index 00000000000..80b74ac90bb --- /dev/null +++ b/app/assets/v2/js/metamask-approval.js @@ -0,0 +1,45 @@ +async function metamaskApproval() { + if (window.ethereum) { + window.web3 = new Web3(ethereum); + is_metamask_approved = await window.ethereum._metamask.isApproved(); + is_metamask_unlocked = await window.ethereum._metamask.isUnlocked(); + + try { + if (is_metamask_unlocked && is_metamask_approved) { + await ethereum.enable(); + } + } catch (error) { + _alert('Permission to connect to metamask rejected. Allow gitcoin to connect to metamask.', 'warning'); + } + } + ask_metamask_connection(); +} + +window.addEventListener('load', metamaskApproval); + +async function approve_metamask() { + try { + await ethereum.enable(); + is_metamask_approved = true; + } catch (error) { + _alert('Permission to connect to metamask rejected. Allow gitcoin to connect to metamask.', 'warning'); + } +} + +function ask_metamask_connection() { + var page_url = $(location).attr('pathname'); + + shown_on = [ '/tip/send/2', '/kudos/send', '/ens' ]; + var len = page_url.length - 1; + + if (page_url.lastIndexOf('/') === len) { + page_url = page_url.substring(0, len); + } + if ($.inArray(page_url, shown_on) != -1 && !is_metamask_approved) { + _alert('Metamask not connected. ', 'error'); + $('#metamask_connect').css('background', 'none'); + $('#metamask_connect').css('color', 'white'); + $('#metamask_connect').css('border', '2px solid white'); + $('#metamask_connect').css('border-radius', '10px'); + } +} diff --git a/app/assets/v2/js/shared.js b/app/assets/v2/js/shared.js index ad6bb829547..8316d705d29 100644 --- a/app/assets/v2/js/shared.js +++ b/app/assets/v2/js/shared.js @@ -635,10 +635,17 @@ var currentNetwork = function(network) { $('#current-network').text(gettext('Metamask Not Enabled')); $('#navbar-network-banner').html(info); } else if (network == 'locked') { - info = gettext('Web3 locked. Please unlock ') + - 'Metamask'; - $('#current-network').text(gettext('Metamask Locked')); - $('#navbar-network-banner').html(info); + if (is_metamask_approved || !is_metamask_unlocked) { + info = gettext('Web3 locked. Please unlock ') + + 'Metamask'; + $('#current-network').text(gettext('Metamask Locked')); + $('#navbar-network-banner').html(info); + } else { + info = gettext('Metamask not connected. ') + + ''; + $('#current-network').text(gettext('Metamask Not Connected')); + $('#navbar-network-banner').html(info); + } } else { info = gettext('Connect to Mainnet via Metamask'); $('#current-network').text(gettext('Unsupported Network')); @@ -669,10 +676,17 @@ var currentNetwork = function(network) { $('#current-network').text(gettext('Metamask Not Enabled')); $('#navbar-network-banner').html(info); } else if (network == 'locked') { - info = gettext('Web3 locked. Please unlock ') + - 'Metamask'; - $('#current-network').text(gettext('Metamask Locked')); - $('#navbar-network-banner').html(info); + if (is_metamask_approved || !is_metamask_unlocked) { + info = gettext('Web3 locked. Please unlock ') + + 'Metamask'; + $('#current-network').text(gettext('Metamask Locked')); + $('#navbar-network-banner').html(info); + } else { + info = gettext('Metamask not connected. ') + + ''; + $('#current-network').text(gettext('Metamask Not Connected')); + $('#navbar-network-banner').html(info); + } } else { info = gettext('Connect to Rinkeby / Custom RPC via Metamask'); $('#current-network').text(gettext('Unsupported Network')); @@ -708,14 +722,26 @@ var trigger_primary_form_web3_hooks = function() { $('#primary_form').addClass('hidden'); $('.submit_bounty .newsletter').addClass('hidden'); $('#unlock_metamask_error').css('display', 'none'); + $('#connect_metamask_error').css('display', 'none'); $('#no_issue_error').css('display', 'none'); mixpanel_track_once('No Metamask Error', params); + } else if (is_metamask_unlocked && !is_metamask_approved) { + $('#connect_metamask_error').css('display', 'block'); + $('#unlock_metamask_error').css('display', 'none'); + $('#zero_balance_error').css('display', 'none'); + $('#no_metamask_error').css('display', 'none'); + $('#robot_error').removeClass('hidden'); + $('#primary_form').addClass('hidden'); + $('.submit_bounty .newsletter').addClass('hidden'); + $('#no_issue_error').css('display', 'none'); + mixpanel_track_once('Unlock Metamask Error', params); } else if (!web3.eth.coinbase) { $('#unlock_metamask_error').css('display', 'block'); $('#zero_balance_error').css('display', 'none'); $('#no_metamask_error').css('display', 'none'); $('#robot_error').removeClass('hidden'); $('#primary_form').addClass('hidden'); + $('#connect_metamask_error').css('display', 'none'); $('.submit_bounty .newsletter').addClass('hidden'); $('#no_issue_error').css('display', 'none'); mixpanel_track_once('Unlock Metamask Error', params); @@ -725,6 +751,7 @@ var trigger_primary_form_web3_hooks = function() { $('#primary_form').addClass('hidden'); $('.submit_bounty .newsletter').addClass('hidden'); $('#unlock_metamask_error').css('display', 'none'); + $('#connect_metamask_error').css('display', 'none'); $('#no_metamask_error').css('display', 'none'); $('#no_issue_error').css('display', 'none'); mixpanel_track_once('Zero Balance Metamask Error', params); @@ -732,6 +759,7 @@ var trigger_primary_form_web3_hooks = function() { $('#zero_balance_error').css('display', 'none'); $('#unlock_metamask_error').css('display', 'none'); $('#no_metamask_error').css('display', 'none'); + $('#connect_metamask_error').css('display', 'none'); $('#no_issue_error').css('display', 'block'); $('#robot_error').addClass('hidden'); $('#primary_form').removeClass('hidden'); @@ -755,14 +783,23 @@ var trigger_faucet_form_web3_hooks = function() { $('#faucet_form').addClass('hidden'); mixpanel_track_once('No Metamask Error', params); return; + } else if (is_metamask_unlocked && !is_metamask_approved) { + $('#no_metamask_error').css('display', 'none'); + $('#unlock_metamask_error').css('display', 'none'); + $('#connect_metamask_error').css('display', 'block'); + $('#over_balance_error').css('display', 'none'); + $('#faucet_form').addClass('hidden'); } else if (!web3.eth.coinbase) { $('#no_metamask_error').css('display', 'none'); $('#unlock_metamask_error').css('display', 'block'); + $('#connect_metamask_error').css('display', 'none'); + $('#over_balance_error').css('display', 'none'); $('#faucet_form').addClass('hidden'); return; } else if (balance >= faucet_amount) { $('#no_metamask_error').css('display', 'none'); $('#unlock_metamask_error').css('display', 'none'); + $('#connect_metamask_error').css('display', 'none'); $('#over_balance_error').css('display', 'block'); $('#faucet_form').addClass('hidden'); mixpanel_track_once('Faucet Available Funds Metamask Error', params); @@ -770,6 +807,7 @@ var trigger_faucet_form_web3_hooks = function() { $('#over_balance_error').css('display', 'none'); $('#no_metamask_error').css('display', 'none'); $('#unlock_metamask_error').css('display', 'none'); + $('#connect_metamask_error').css('display', 'none'); $('#faucet_form').removeClass('hidden'); } } @@ -780,6 +818,11 @@ var trigger_faucet_form_web3_hooks = function() { mixpanel_track_once('No Metamask Error', params); return; } + if (is_metamask_unlocked && !is_metamask_approved) { + $('#unlock_metamask_error').css('display', 'none'); + $('#connect_metamask_error').css('display', 'block'); + $('#faucet_form').addClass('hidden'); + } if (!web3.eth.coinbase) { $('#unlock_metamask_error').css('display', 'block'); $('#faucet_form').addClass('hidden'); @@ -816,7 +859,7 @@ function getNetwork(id) { } // figure out what version of web3 this is, whether we're logged in, etc.. -var listen_for_web3_changes = function() { +var listen_for_web3_changes = async function() { if (!document.listen_for_web3_iterations) { document.listen_for_web3_iterations = 1; @@ -831,6 +874,7 @@ var listen_for_web3_changes = function() { currentNetwork('locked'); trigger_form_hooks(); } else { + is_metamask_unlocked = true; web3.eth.getBalance(web3.eth.coinbase, function(errors, result) { if (typeof result != 'undefined') { document.balance = result.toNumber(); @@ -848,6 +892,13 @@ var listen_for_web3_changes = function() { } }); } + if (window.ethereum) { + is_metamask_approved = await window.ethereum._metamask.isApproved(); + is_metamask_unlocked = await window.ethereum._metamask.isUnlocked(); + if (is_metamask_approved && is_metamask_unlocked) { + await ethereum.enable(); + } + } }; var actions_page_warn_if_not_on_same_network = function() { diff --git a/app/dashboard/templates/bounty/fulfill.html b/app/dashboard/templates/bounty/fulfill.html index 7948802b0ba..5a95bd4bfcb 100644 --- a/app/dashboard/templates/bounty/fulfill.html +++ b/app/dashboard/templates/bounty/fulfill.html @@ -35,6 +35,7 @@ {% include 'shared/no_metamask_error.html' %} {% include 'shared/zero_balance_error.html' %} {% include 'shared/unlock_metamask.html' %} + {% include 'shared/connect_metamask.html' %}