-
-
Save Dours-d/87e6bc3b00d15e159399de22d28bac1c to your computer and use it in GitHub Desktop.
HEX pull interest to date
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
const Web3 = require('web3'); | |
const compiledContractABI = require('./HEX.abi.json'); | |
const hexAddr = "0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39"; | |
const findStakeAndIndex = async (addr, stakeId) => { | |
let stakes = await hex.stakeList(addr); | |
for(let i = 0; i < stakes.length; i++){ | |
if(stakes[i].stakeId === stakeId){ | |
return [i, stakes[i]]; | |
} | |
} | |
return []; | |
} | |
const HEARTS_UINT_SHIFT = 72n; | |
const HEARTS_MASK = (1n << HEARTS_UINT_SHIFT) - 1n; | |
const SATS_UINT_SHIFT = 56n; | |
const SATS_MASK = (1n << SATS_UINT_SHIFT) - 1n; | |
const decodeDailyData = (encDay) => { | |
let v = BigInt(encDay); | |
let payout = v & HEARTS_MASK; | |
v = v >> HEARTS_UINT_SHIFT; | |
let shares = v & HEARTS_MASK; | |
v = v >> HEARTS_UINT_SHIFT; | |
let sats = v & SATS_MASK; | |
return {payout, shares, sats}; | |
} | |
const interestForRange = (dailyData, myShares) => { | |
return dailyData.reduce((s, d) => s + interestForDay(d, myShares), 0n); | |
} | |
const interestForDay = (dayObj, myShares) => { | |
return myShares * dayObj.payout / dayObj.shares; | |
} | |
const encodeData = (dayObj) => { | |
let v = dayObj.sats; | |
v = v << HEARTS_UINT_SHIFT; | |
v |= dayObj.shares; | |
v = v << HEARTS_UINT_SHIFT; | |
v |= dayObj.payout; | |
return v; | |
} | |
const getDataRange = async (hex, b, e) => { | |
const dataRange = await hex | |
.methods | |
.dailyDataRange(b, e) | |
.call(); | |
const data = []; | |
for(let i = 0; i < dataRange.length; i++){ | |
data.push(decodeDailyData(dataRange[i])); | |
} | |
return data; | |
}; | |
const getStake = async (hex, addr, sid) => { | |
let stakeCount = await hex.methods.stakeCount(addr).call(); | |
for(let i = 0; i < stakeCount; i++){ | |
let stake = await hex.methods.stakeLists(addr, i).call(); | |
if(stake.stakeId === sid.toString()){ | |
return stake; | |
} | |
} | |
} | |
const getStakeByIndex = async (hex, addr, idx) => { | |
let stake = await hex.methods.stakeLists(addr, idx).call(); | |
return stake; | |
} | |
const getLastDataDay = async (hex) => { | |
let globalInfo = await hex.methods.globalInfo().call(); | |
const lastDay = globalInfo[4]; | |
return Number.parseInt(lastDay); | |
} | |
const getInterestToDate = async (hex, addr, stakeId, stakeIndex, stake) => { | |
let s; | |
if(stake !== undefined){ | |
s = stake; | |
} else if(stakeIndex !== undefined){ | |
s = await getStakeByIndex(hex, addr, stakeIndex); | |
} else { | |
s = await getStake(hex, addr, stakeId); | |
} // Not validating that I have both things correct/matching, error detection needed | |
const b = Number.parseInt(s.lockedDay); | |
const e = await getLastDataDay(hex); // ostensibly "today" | |
if (b >= e) { | |
//not started - error | |
return 0n; | |
} else { | |
const data = await getDataRange(hex, b, e); | |
return interestForRange(data, BigInt(s.stakeShares)); | |
} | |
} | |
const getTotalValue = async (hex, addr, stakeId, stakeIndex) => { | |
let stake; | |
if(stakeIndex !== undefined){ | |
stake = await getStakeByIndex(hex, addr, stakeIndex); | |
} else { | |
stake = await getStake(hex, addr, stakeId); | |
} | |
const interest = await getInterestToDate(hex, addr, stakeId, stakeIndex, stake); | |
return BigInt(stake.stakedHearts) + interest; | |
} | |
let uri = null; // some JSON RPC uri, like infura | |
const web3 = new Web3(uri); | |
let hex = new web3.eth.Contract(compiledContractABI, hexAddr); | |
// examples | |
getInterestToDate(hex, testAddr, undefined, 5) | |
.then(console.log); | |
getTotalValue(hex, testAddr, testStakeId) | |
.then(console.log); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment