244 lines
8.6 KiB
HTML
244 lines
8.6 KiB
HTML
<!doctype html>
|
|
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
|
<title>Whistlebox</title>
|
|
<meta name="title" content="Whistlebox" />
|
|
<meta name="description" content="Put your sensitive disclosures here (don't really, it's a proof of concept)." />
|
|
<meta name="author" content="Zev Averbach">
|
|
|
|
<meta property="og:title" content="Whistlebox">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:url" content="https://web3.averba.ch">
|
|
<meta property="og:description" content="Put your sensitive disclosures here (don't really, it's a proof of concept).">
|
|
<meta property="og:image" content="image.png">
|
|
|
|
<link rel="icon" href="/favicon.ico">
|
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
|
<!-- Facebook -->
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:url" content="https://web3.averba.ch/">
|
|
<meta property="og:title" content="Whistlebox">
|
|
<meta property="og:description" content="I want to meet you! Send me a wave now!">
|
|
<meta property="og:image" content="https://s3.amazonaws.com/cdn.buildspace.so/courses/ethereum-smart-contracts/metadata.png">
|
|
|
|
<!-- Twitter -->
|
|
<meta property="twitter:card" content="summary_large_image">
|
|
<meta property="twitter:url" content="https://web3.averba.ch/">
|
|
<meta property="twitter:title" content="Whistlebox">
|
|
<meta property="twitter:description" content="Put your sensitive disclosures here (don't really, it's a proof of concept).">
|
|
<meta property="twitter:image"
|
|
content="https://s3.amazonaws.com/cdn.buildspace.so/courses/ethereum-smart-contracts/metadata.png">
|
|
<style>
|
|
|
|
#confirm {
|
|
color: red;
|
|
display: none;
|
|
text-align: center;
|
|
margin-top: 1em;
|
|
}
|
|
|
|
#connectWallet {
|
|
display: none;
|
|
}
|
|
|
|
.mainContainer {
|
|
display: flex;
|
|
justify-content: center;
|
|
padding: 2em 0;
|
|
width: 100%;
|
|
margin-top: 64px;
|
|
}
|
|
|
|
.dataContainer {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
max-width: 600px;
|
|
}
|
|
|
|
form {
|
|
margin: 0 auto;
|
|
padding: 1em 0;
|
|
}
|
|
|
|
textarea {
|
|
margin: 1em 3em;
|
|
resize: none;
|
|
font-size: 1em;
|
|
border: solid 2px pink;
|
|
outline: none;
|
|
padding: 1em;
|
|
}
|
|
|
|
.header {
|
|
text-align: center;
|
|
font-size: 32px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.bio {
|
|
text-align: center;
|
|
color: gray;
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.whistleButton {
|
|
cursor: pointer;
|
|
text-align: center;
|
|
margin: 0 auto;
|
|
padding: 8px;
|
|
width: 200px;
|
|
border: 0;
|
|
background-color: yellow;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
|
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
|
sans-serif;
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
}
|
|
|
|
code {
|
|
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
|
monospace;
|
|
}
|
|
</style>
|
|
<script type="text/javascript" src="ethers.js"></script>
|
|
|
|
|
|
</head>
|
|
|
|
<body onload="onLoad()">
|
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
|
|
|
|
<div class="mainContainer">
|
|
|
|
<div class="dataContainer">
|
|
<div class="header">
|
|
👋 Hey there!
|
|
</div>
|
|
|
|
<div class="bio">
|
|
Hey, I'm Zev and this is a place to put sensitive whistleblower disclosures (not really! it's a proof of concept) into the ethereum blockchain.
|
|
</div>
|
|
|
|
<button onclick="connectWallet()" id="connectWallet">Connect Wallet</button>
|
|
|
|
<form action="javascript:;" onsubmit="whistle()" id="whistleForm">
|
|
<label for=disclosure>
|
|
Sensitive Disclosure
|
|
</label>
|
|
</form>
|
|
|
|
<textarea autofocus rows="5" cols="30" name=disclosure></textarea>
|
|
|
|
<button type=submit form="whistleForm" value="Disclose" class="whistleButton">
|
|
<b>Disclose</b> (⌘/ctrl-enter)
|
|
</button>
|
|
<div id=confirm>Disclosure sent!</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
let currentAccount
|
|
const contractAddress = "0x085c977Cb9b8B7afc11FB7ae66B472fD58362B31"
|
|
const box = document.getElementsByName("disclosure")[0]
|
|
let contractABI
|
|
|
|
const getContractABI = async () => {
|
|
const abi = await fetch('./whistleBox.json')
|
|
abiJson = await abi.json()
|
|
return abiJson.abi
|
|
}
|
|
|
|
getContractABI().then(result => contractABI = result)
|
|
console.log(contractABI)
|
|
|
|
const onLoad = async () => {
|
|
await walletIsConnected()
|
|
setInterval(() => walletIsConnected(), 1000)
|
|
}
|
|
|
|
const getEthObj = async () => {
|
|
if (!window.ethereum) {
|
|
throw "Make sure you have metamask!"
|
|
} else {
|
|
console.log("We have the ethereum object", window.ethereum)
|
|
}
|
|
return window.ethereum
|
|
}
|
|
|
|
const walletIsConnected = async () => {
|
|
try {
|
|
const ethereum = await getEthObj()
|
|
const accounts = await ethereum.request({ method: 'eth_accounts' })
|
|
|
|
if (accounts.length !== 0) {
|
|
currentAccount = accounts[0]
|
|
console.log("found an authorized account:", currentAccount)
|
|
hideElement("connectWallet")
|
|
} else {
|
|
console.log("no authorized account found")
|
|
showElement("connectWallet")
|
|
}
|
|
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
}
|
|
|
|
const connectWallet = async () => {
|
|
try {
|
|
const ethereum = await getEthObj()
|
|
currentAccount = await ethereum.request({ method: "eth_requestAccounts" })[0]
|
|
} catch (error) {
|
|
console.log(error)
|
|
showElement("connectWallet")
|
|
}
|
|
hideElement("connectWallet")
|
|
}
|
|
|
|
const whistle = async () => {
|
|
try {
|
|
const ethereum = await getEthObj()
|
|
//const disclosure = box.value
|
|
// box.value = ""
|
|
const provider = new ethers.providers.Web3Provider(ethereum)
|
|
const signer = provider.getSigner()
|
|
const contract = new ethers.Contract(contractAddress, contractABI, signer)
|
|
let tips = await contract.getAllTips()
|
|
console.log('okay, got tips')
|
|
console.log(tips)
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
}
|
|
|
|
const confirm = document.getElementById("confirm")
|
|
|
|
const showConfirm = () => {
|
|
confirm.style.display = "block"
|
|
setTimeout(() => confirm.style.display = "none", 5000)
|
|
}
|
|
|
|
const showElement = id => document.getElementById(id).style.display = "block"
|
|
const hideElement = id => document.getElementById(id).style.display = "none"
|
|
|
|
document.addEventListener('keydown', (event) => {
|
|
if(event.ctrlKey && event.key == "Enter" || event.metaKey && event.key == "Enter") {
|
|
whistle()
|
|
box.blur()
|
|
}
|
|
})
|
|
</script>
|
|
</body>
|
|
</html>
|