-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcli.js
93 lines (86 loc) · 4.18 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env node
const Web3 = require('web3');
const Web3Utils = require('web3-utils');
const moment = require('moment');
const UBIABI = require('./UBIABI.json');
const ERC20ABI = require('./ERC20ABI.json');
const {getPrivateKey} = require('./utils');
const cron = require('node-cron');
const UBI_CONTRACT_ADDRESS = '0xd253A5203817225e9768C05E5996d642fb96bA86';
(async () => {
const web3 = new Web3(new Web3.providers.HttpProvider('https://rpc.fuse.io/'));
const mainAccount = web3.eth.accounts.privateKeyToAccount(await getPrivateKey());
web3.eth.defaultAccount = mainAccount;
const ubiContract = new web3.eth.Contract(UBIABI, UBI_CONTRACT_ADDRESS, {chainId: 122, from: mainAccount.address});
await claim(web3, mainAccount, ubiContract);
const startMoment = await getNextClaimDate(ubiContract);
const randomMinute = Math.floor(Math.random() * 60);
const randomSecond = Math.floor(Math.random() * 60);
startMoment.add(randomMinute, 'minutes');
startMoment.add(randomSecond, 'seconds');
startMoment.add(1, 'hours'); // Workaround daylight savings time bug.
console.log('');
console.log(`Claim offset set to: ${randomMinute}:${String(randomSecond).padStart(2, '0')}`);
console.log('Offset is to avoid higher transaction fees/instability if everyone claims at once.')
console.log('');
console.log('Make sure to buy some gas:')
console.log('https://git.io/JtXAb');
console.log('');
console.log(`Will automatically claim G$ every day if this script is left running, starting ${startMoment.format('lll')}.`);
console.log('WARNING: this will only work if this computer is kept awake e.g. used for mining or a server.')
console.log(`${moment().format('lll')}: Going to sleep!`);
cron.schedule(`${randomSecond} ${randomMinute} ${startMoment.hour()} * * *`, () => {
console.log('');
console.log(`${moment().format('lll')}: Woke up, time to make a claim!`);
claim(web3, mainAccount, ubiContract);
});
})();
async function claim(web3, mainAccount, ubiContract) {
const claimAmount = await ubiContract.methods.checkEntitlement.call().then(_ => _.toNumber());
if (claimAmount > 0) {
console.log(`Claiming: ${claimAmount/100} G$`);
try {
await sendTransaction(web3, ubiContract.methods.claim(), UBI_CONTRACT_ADDRESS, mainAccount);
console.log('UBI collected.');
await printNextClaimDate(web3, mainAccount, ubiContract);
} catch (e) {
console.error('Claim failed, try using the website wallet.', e);
}
} else {
console.log('No claim available right now.');
await printNextClaimDate(web3, mainAccount, ubiContract);
}
}
async function getNextClaimDate(ubiContract) {
const startMoment = await ubiContract.methods.periodStart.call().then(_ => moment(_.toNumber() * 1000));
const curDay = await ubiContract.methods.currentDay.call().then(_ => _.toNumber());
startMoment.add(curDay + 1, 'days');
return startMoment;
}
async function printNextClaimDate(web3, mainAccount, ubiContract) {
const erc20Contract = new web3.eth.Contract(ERC20ABI,'0x495d133B938596C9984d462F007B676bDc57eCEC', {from: mainAccount.address, chainId: 122});
const startMoment = await getNextClaimDate(ubiContract);
console.log(`Next claim will be available: ${startMoment.format('lll')}`);
const balance = await erc20Contract.methods.balanceOf(mainAccount.address).call().then(_ => _.toNumber());
console.log(`Balance: ${balance/100} G$`);
}
async function sendTransaction(web3, call, to, mainAccount) {
const gas = (await call.estimateGas().catch(e => console.log('estimate gas failed ', e))) || 200000;
const gasPrice = (await web3.eth.getGasPrice().then(Web3Utils.toBN)).toString();
const tx = {gas: gas*2, gasPrice, from: mainAccount.address, data: call.encodeABI(), to};
const signedTx = await web3.eth.accounts.signTransaction(tx, mainAccount.privateKey);
const results = await new Promise((resolve, reject) => {
web3.eth.sendSignedTransaction(signedTx.rawTransaction)
.once('transactionHash', h => {
console.log('Transaction: ' + h);
})
.once('error', e => {
console.log('sendTransaction error: ', e);
reject(e);
})
.once('receipt', receipt => {
resolve(receipt);
});
});
return results;
}