Skip to content

Instantly share code, notes, and snippets.

@WietseWind
Created June 20, 2024 14:26
Show Gist options
  • Save WietseWind/c80054639f72a677012073efe25954ba to your computer and use it in GitHub Desktop.
Save WietseWind/c80054639f72a677012073efe25954ba to your computer and use it in GitHub Desktop.
Calculate Balance Adjustment on Xahau
import fetch from 'node-fetch'
import { hookStateXLFtoBigNumber } from './xfl.mjs'
// Credits: https://github.com/tequdev/xahau-reward-claim/blob/main/src/app/ClaimReward.tsx
const account = 'rTeLeproT3BVgjWoYrDYpKbBLXPaVMkge'
const RPC_ENDPOINT = 'https://xahau.network'
const toUnixTimestamp = ts => ts + 946684800
const rpc = async req => {
const call = await fetch(`${ RPC_ENDPOINT}`, { method: 'POST', body: JSON.stringify(req) }) const json = await call.json()
return json?.result
}
const [
{ node: { HookStateData: RewardRate }, },
{ node: { HookStateData: RewardDelay }, },
{ account_data: { Balance: BalanceInDrops, RewardAccumulator: RewardAccumulatorHex, RewardLgrFirst, RewardLgrLast, RewardTime, PreviousTxnLgrSeq } },
{ ledger: { ledger_index: LedgerIndex, close_time: LastLedgerCloseTime } },
] = await Promise.all([
rpc({ method: 'ledger_entry', params: [ { hook_state: { account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', key: '0000000000000000000000000000000000000000000000000000000000005252', /* RR */ namespace_id: '0000000000000000000000000000000000000000000000000000000000000000', }, }, ], }),
rpc({ method: 'ledger_entry', params: [ { hook_state: { account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', key: '0000000000000000000000000000000000000000000000000000000000005244', /* RD */ namespace_id: '0000000000000000000000000000000000000000000000000000000000000000', }, }, ], }),
rpc({ method: 'account_info', params: [ { account, }, ], }),
rpc({ method: 'ledger', params: [ { ledger_index: 'validated', }, ], }),
])
console.log({ rewardDelay: hookStateXLFtoBigNumber(RewardDelay) })
const Balance = Number(BalanceInDrops) / 1000000
const TimeDiffSinceAdjustmentPeriodStart = LastLedgerCloseTime - RewardTime
const CanClaim = TimeDiffSinceAdjustmentPeriodStart >= hookStateXLFtoBigNumber(RewardDelay)
const RewardAccumulator = parseFloat(BigInt(`0x${RewardAccumulatorHex}`).toString())
console.log('Adjustment Rate (pct) per adjustment interval', hookStateXLFtoBigNumber(RewardRate))
console.log('Adjustment interval in days', hookStateXLFtoBigNumber(RewardDelay) / 60 / 60 / 24)
console.log('Last claim Timestamp', toUnixTimestamp(RewardTime))
console.log('Current ledger close Timestamp', toUnixTimestamp(LastLedgerCloseTime))
console.log('Claim diff (seconds) && claimable', TimeDiffSinceAdjustmentPeriodStart, CanClaim)
let accumulator = RewardAccumulator
const cur = LedgerIndex
const elapsed = cur - RewardLgrFirst
const elapsed_since_last = LedgerIndex - RewardLgrLast
const bal = Balance
if (bal > 0 && elapsed_since_last > 0) accumulator += bal * elapsed_since_last
const xfl_accum = accumulator
const xfl_elapsed = elapsed
let xfl_reward = xfl_accum / xfl_elapsed
xfl_reward = hookStateXLFtoBigNumber(RewardRate) * xfl_reward
console.log({
toexpect_atsamebalance_atclaim: xfl_reward,
buildup:
CanClaim
? xfl_reward
: xfl_reward / hookStateXLFtoBigNumber(RewardDelay) * TimeDiffSinceAdjustmentPeriodStart
})
// https://github.com/tequdev/xahau-reward-claim/blob/main/src/lib/xahau/xfl.ts
export function get_exponent(xfl) {
if (xfl < 0n)
throw "Invalid XFL"
if (xfl == 0n)
return 0n
return ((xfl >> 54n) & 0xFFn) - 97n
}
export function get_mantissa(xfl) {
if (xfl < 0n)
throw "Invalid XFL"
if (xfl == 0n)
return 0n
return xfl - ((xfl >> 54n) << 54n)
}
export function is_negative(xfl) {
if (xfl < 0n)
throw "Invalid XFL"
if (xfl == 0n)
return false
return ((xfl >> 62n) & 1n) == 0n
}
export function to_string(xfl) {
if (xfl < 0n)
throw "Invalid XFL"
if (xfl == 0n)
return "<zero>"
return (is_negative(xfl) ? "-" : "+") + get_mantissa(xfl).toString() + "E" + get_exponent(xfl).toString()
}
export const xflToFloat = xfl => parseFloat(to_string(xfl))
export const changeEndianness = str => str.match(/[a-f0-9]{2}/ig).reverse().join('')
export const hookStateXLFtoBigNumber = (stateData) => xflToFloat(BigInt(`0x${changeEndianness(stateData)}`))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment