Skip to content

Commit

Permalink
kind of working version
Browse files Browse the repository at this point in the history
  • Loading branch information
ericet committed Nov 14, 2022
1 parent 19a6b23 commit d21ee15
Show file tree
Hide file tree
Showing 7 changed files with 327 additions and 55 deletions.
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
},
"dependencies": {
"@ethersproject/wallet": "^5.7.0",
"axios": "^1.1.3",
"axios": "^0.21.1",
"core-js": "^3.8.3",
"ethers": "^5.7.2",
"feather-icons": "^4.29.0",
"node-polyfill-webpack-plugin": "^2.0.1",
"vue": "^3.2.13",
"vue-router": "^4.0.3",
"vuex": "^4.0.2"
"vuex": "^4.0.2",
"web3": "^1.8.1"
},
"devDependencies": {
"@babel/core": "^7.12.16",
Expand Down
37 changes: 37 additions & 0 deletions src/components/KeyVote.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<div class="flex flex-col justify-center items-center">
<button
type="button"
@click="vote"
class="mt-4 mb-8 text-white bg-gradient-to-r from-blue-500 via-blue-600 to-blue-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800 font-medium rounded-lg text-sm px-5 py-2.5 text-center"
>
Vote
</button>
</div>
</template>
<script>
import { getWallet } from '../libs/wallet';
import { hasVoted, vote, getVotingPowers } from '../libs/snapshot';
export default {
props: ['accounts'],
methods: {
async vote() {
for (let ac of this.accounts) {
let key = ac.key;
let proposals = ac.proposals;
this.startVoting(key, proposals);
}
},
async startVoting(key, proposals) {
let wallet = getWallet(key);
for (let proposal of proposals) {
let isVoted = await hasVoted(wallet.address, proposal.id);
let vp = await getVotingPowers(proposal.id, wallet.address);
if (!isVoted && vp>0) {
await vote(wallet, proposal.space, proposal.id, proposal.vote + 1);
}
}
},
},
};
</script>
27 changes: 25 additions & 2 deletions src/components/KeysInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,22 @@
"
placeholder="One private key per line"
></textarea>
<KeyVote :accounts="accounts" />
</div>
</template>

<script>
import { validatePrivateKey } from "../libs/utils";
import KeyVote from "@/components/KeyVote.vue";
export default {
props: ["proposals"],
components: { KeyVote },
data() {
return {
input: "",
keys: [],
accounts:[],
};
},
methods: {
Expand All @@ -44,10 +48,29 @@ export default {
if (input.length > 0 && validatePrivateKey(input.trim())) {
this.keys.push(input.trim());
}
else{
console.log("NOT private key")
}
if(this.proposals){
this.getVoteWallet();
}
},
getVoteWallet() {
this.accounts = [];
for (let key of this.keys) {
let proposals = [];
for (let proposal of this.proposals) {
proposals.push({
id: proposal.id,
vote: proposal.vote,
space: proposal.space,
});
}
this.accounts.push({
key: key,
proposals: proposals,
});
}
console.log(this.accounts);
},
},
};
Expand Down
10 changes: 10 additions & 0 deletions src/config/spaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,14 @@ export const spacesList = [
id: "sushigov.eth",
name: 'Sushi',
},
{
id: "snapshot.dcl.eth",
name:"Decentraland"
},{
id:"hop.eth",
name: "Hop Exchange"
},{
id: "gnosis.eth",
name:"GnosisDAO"
}
];
214 changes: 214 additions & 0 deletions src/libs/snapshot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
const { ethers } = require('ethers')
const web3 = require('web3')
const axios = require("axios")

const provider = new ethers.providers.JsonRpcProvider("https://rpc.ankr.com/eth")

async function get_signature (account, signData, provider) {
const { domain, types, message } = signData.data
const signer = new ethers.Wallet(account.privateKey, provider)
return await signer._signTypedData(domain, types, message)
}

async function send_vote_request (data) {
const config = {
method: 'post',
url: 'https://hub.snapshot.org/api/msg',
headers: {
'authority': 'hub.snapshot.org',
'accept': 'application/json',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
'content-type': 'application/json',
'origin': 'https://snapshot.org',
'referer': 'https://snapshot.org/',
'sec-ch-ua': '"Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'
},
data: JSON.stringify(data)
};

try {
const res = await axios(config)
if (res.data.id) {
console.log(`${data.address} 投票成功`);
}
} catch (error) {
console.log(`${data.address} 投票失败`, JSON.stringify(error.response.data));
}
}

async function vote (account, space, proposal, choice) {
const checksum_address = web3.utils.toChecksumAddress(account.address)
const data = {
"address": checksum_address,
"data": {
"domain": {
"name": "snapshot",
"version": "0.1.4"
},
"types": {
"Vote": [
{
"name": "from",
"type": "address"
},
{
"name": "space",
"type": "string"
},
{
"name": "timestamp",
"type": "uint64"
},
{
"name": "proposal",
"type": "string"
},
{
"name": "choice",
"type": "uint32"
},
{
"name": "reason",
"type": "string"
},
{
"name": "app",
"type": "string"
}
]
},
"message": {
"space": space,
"proposal": proposal,
"choice": Number(choice),
"app": "snapshot",
"reason": "",
"from": checksum_address,
"timestamp": Math.floor(Date.now() / 1000)
}
}
}
data.sig = await get_signature(account, data, provider)
await send_vote_request(data)
}
async function hasVoted (address, proposalId) {
const url = 'https://hub.snapshot.org/graphql';
const data = {
query: `query Votes {
votes (
first: 1
where: {
proposal: "${proposalId}",
voter: "${address}"
}
) {
id
voter
created
vp
choice
space {
id
}
}
}
`
}
const res = await axios.post(url, data);
return res.data.data.votes.length > 0;
}

async function getProposal (proposalId) {
const response = await fetch('https://hub.snapshot.org/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: `{"operationName":"Proposal","variables":{"id":"${proposalId}"},"query":"query Proposal($id: String!) {\\n proposal(id: $id) {\\n id\\n ipfs\\n title\\n body\\n choices\\n start\\n end\\n snapshot\\n state\\n author\\n created\\n plugins\\n network\\n type\\n strategies {\\n name\\n network\\n params\\n }\\n space {\\n id\\n name\\n }\\n scores_state\\n scores\\n scores_by_strategy\\n scores_total\\n votes\\n }\\n}"}`,
})

return JSON.parse(await response.text()).data.proposal
}


async function getVotingPowers (proposalId, address) {
const proposal = await getProposal(proposalId);
const response = await fetch('https://score.snapshot.org', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
method: "get_vp",
params: {
space: proposal.space.id,
delegation: false,
network: proposal.network,
snapshot: parseInt(proposal.snapshot),
strategies: proposal.strategies,
address: address,
}
})
})

let vp = (await response.json()).result.vp;
return vp;
}

async function get_active_proposals (space, simple) {
const url = 'https://hub.snapshot.org/graphql?'
const data = {
query: `query Proposals {
proposals(first: 20, skip: 0, where: {space_in: ["${space}"], state: "active"}, orderBy: "created", orderDirection: desc) {
id
title
body
choices
start
end
snapshot
state
author
type
app
space {
id
name
}
}
}`
}
const res = await axios.post(url, data)
if (simple) {
return res.data.data.proposals.map(item => {
return {
id: item.id,
title: item.title,
type: item.type,
choices: item.choices,
}
})
}
return res.data.data.proposals
}

async function vote_on (account, space, choice) {
const proposals = await get_active_proposals(space)
for (const proposal of proposals) {
console.log(`Account: ${account.id} 投票进行中: ${space} - ${proposal.title} - ${proposal.choices[choice - 1]}`);
await vote(account, space, proposal.id, choice)
}
}

module.exports = {
vote_on,
vote,
hasVoted,
getVotingPowers
}
11 changes: 11 additions & 0 deletions src/libs/wallet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const { ethers } = require('ethers')

function getWallet(privateKey){
let wallet = new ethers.Wallet(privateKey);

return wallet;
}

module.exports={
getWallet
}
Loading

0 comments on commit d21ee15

Please sign in to comment.