Created
March 13, 2022 01:41
-
-
Save KenoLeon/f52131754f63cf9c71e18ddd523fddde to your computer and use it in GitHub Desktop.
Standalone MetaMask Signer for Medium Article tutorial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<!-- Standalone MetaMask Signer for A Medium Article: Signing messages in Ethereum medium.com/@k3no--> | |
<!-- Not to be used in production, just for educational purposes. --> | |
<head> | |
<!-- Required meta tags --> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- Bootstrap CSS --> | |
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" | |
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> | |
<style> | |
pre { | |
overflow-x: auto; | |
white-space: pre-wrap; | |
white-space: -moz-pre-wrap; | |
white-space: -pre-wrap; | |
white-space: -o-pre-wrap; | |
word-wrap: break-word; | |
} | |
</style> | |
<script> | |
var globalAccount; | |
var globalSignature; | |
window.onload = function () { | |
// web3 instance for signature recovery | |
const web3 = new Web3(window.ethereum); | |
if (typeof window.ethereum !== 'undefined') { | |
console.log('MetaMask is installed!'); | |
document.getElementById("debugContent").innerHTML = "MetaMask is installed!"; | |
document.getElementById("metaMaskState").innerHTML = JSON.stringify(window.ethereum._state); | |
} else { | |
console.log('MetaMask is not installed!'); | |
document.getElementById("debugContent").innerHTML = "MetaMask is not installed!"; | |
} | |
const ethereumButton = document.querySelector('.launchButton'); | |
const signButton = document.querySelector('.signMessageButton'); | |
const verifyButton = document.querySelector('.verifyMessageButton'); | |
const showAccount = document.querySelector('.showAccount'); | |
ethereumButton.addEventListener('click', () => { | |
//Get the main account from MetaMask needs manual reload. | |
getAccount(); | |
}); | |
signButton.addEventListener('click', () => { | |
signMessage(); | |
}); | |
verifyButton.addEventListener('click', () => { | |
verifyMessage(); | |
}); | |
async function signMessage() { | |
const message = 'Very Message Such Wow'; | |
document.getElementById("messageString").innerHTML = JSON.stringify(message); | |
try { | |
const from = globalAccount; | |
console.log('from : ' + from); | |
const msg = `0x${bops.from(message, 'utf8').toString('hex')}`; | |
document.getElementById("messageHex").innerHTML = JSON.stringify(msg); | |
console.log('msg : ' + msg); | |
const sign = await ethereum.request({ | |
method: 'personal_sign', | |
params: [msg, from, 'Random text'], | |
}); | |
console.log('sign : ' + sign); | |
globalSignature = sign; | |
document.getElementById("signature").innerHTML = JSON.stringify(sign); | |
} catch (err) { | |
console.error(err); | |
} | |
} | |
async function verifyMessage() { | |
const message = 'Very Message Such Wow'; | |
try { | |
const from = globalAccount; | |
const msg = `0x${bops.from(message, 'utf8').toString('hex')}`; | |
const recoveredAddr = web3.eth.accounts.recover(msg, globalSignature); | |
console.log('recoveredAddr : ' + recoveredAddr); | |
document.getElementById("recoveredAddress").innerHTML = "Recovered Address: " + | |
recoveredAddr | |
if (recoveredAddr.toLowerCase() === from.toLowerCase()) { | |
console.log(`Successfully ecRecovered signer as ${recoveredAddr}`); | |
document.getElementById('result').innerHTML = `Verified !`; | |
} else { | |
console.log( | |
`Failed to verify signer when comparing ${recoveredAddr} to ${from}`, | |
); | |
document.getElementById('result').innerHTML = `Not Verified :(`; | |
} | |
} catch (err) { | |
console.error(err); | |
} | |
} | |
async function getAccount() { | |
const accounts = await ethereum.request({ | |
method: 'eth_requestAccounts' | |
}); | |
const account = accounts[0]; | |
globalAccount = accounts[0]; | |
showAccount.innerHTML = "Account: " + account; | |
document.getElementById("metaMaskState").innerHTML = JSON.stringify(window.ethereum._state); | |
} | |
} | |
</script> | |
<title>MetaMask debugging and testing</title> | |
</head> | |
<body> | |
<div class="container"> | |
<br> | |
<br> | |
<div class="row"> | |
<div class="col-1"> | |
</div> | |
<div class="col-10"> | |
<div class="alert alert-dark"> | |
<h5 class="alert-heading">MetaMask Debuggin and Testing .</h5> | |
</div> | |
<div class="alert alert-info" role="alert"> | |
<h4 class="alert-heading">DEBUG</h4> | |
<div id="debugContent"> | |
No Javascript detected! | |
</div> | |
<span class="badge rounded-pill bg-info text-dark showAccount"></span> | |
<h5>window.ethereum._state :</h5> | |
<div> | |
<pre id="metaMaskState"></pre> | |
</div> | |
<h5>Message String:</h5> | |
<div> | |
<pre id="messageString"></pre> | |
</div> | |
<h5>Message Hex:</h5> | |
<div> | |
<pre id="messageHex"></pre> | |
</div> | |
<h5>Signature :</h5> | |
<div> | |
<pre id="signature"></pre> | |
</div> | |
<h5>Verification :</h5> | |
<div> | |
<pre id="recoveredAddress"></pre> | |
<br> | |
</div> | |
<h5>RESULT :</h5> | |
<div id="result"></div> | |
</div> | |
<button type="button" class="btn btn-secondary btn-lg btn-block launchButton">Connect Launch Login | |
Metamask</button> | |
<br> | |
<br> | |
<button type="button" class="btn btn-secondary btn-lg btn-block signMessageButton">Sign Message</button> | |
<br> | |
<br> | |
<button type="button" class="btn btn-secondary btn-lg btn-block verifyMessageButton">Verify | |
Message</button> | |
</div> | |
<div class="col-1"> | |
</div> | |
</div> | |
<br><br><br> | |
</div> | |
<!-- Bootstrap Bundle with Popper --> | |
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" | |
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"> | |
</script> | |
<!-- Using Bops instead of Buffer (Node) for portability --> | |
<script src="https://cdn.jsdelivr.net/gh/chrisdickinson/bops@master/dist/bops.js" type="module"></script> | |
<!-- Also you will need some utils, web3.js instead of @Metamask/eth-sig-util --> | |
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment