Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: move unstake data fetch into a separate component #20

Merged
merged 6 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
234 changes: 25 additions & 209 deletions src/LiNEAR.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ const NEAR_DECIMALS = 24;
const LiNEAR_DECIMALS = 24;
const BIG_ROUND_DOWN = 0;
const MIN_BALANCE_CHANGE = 0.5;
//time in ms
const SECONDS = 1000;
const MINUTES = 60 * SECONDS;
const HOURS = 60 * MINUTES;

function isValid(a) {
if (!a) return false;
Expand Down Expand Up @@ -41,201 +37,11 @@ function getConfig(network) {
}
const config = getConfig(context.networkId);

function getNearBalance(accountId) {
const account = fetch(config.nodeUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: "dontcare",
method: "query",
params: {
request_type: "view_account",
finality: "final",
account_id: accountId,
},
}),
});
const { amount, storage_usage } = account.body.result;
const COMMON_MIN_BALANCE = 0.05;
if (!amount) return "-";
const availableBalance = Big(amount || 0).minus(
Big(storage_usage).mul(Big(10).pow(19))
);
const balance = availableBalance
.div(Big(10).pow(NEAR_DECIMALS))
.minus(COMMON_MIN_BALANCE);
return balance.lt(0) ? "0" : balance.toFixed(5, BIG_ROUND_DOWN);
}

function getLinearBalance(accountId) {
const linearBalanceRaw = Near.view(config.contractId, "ft_balance_of", {
account_id: accountId,
});
if (!linearBalanceRaw) return "-";
const balance = Big(linearBalanceRaw).div(Big(10).pow(LiNEAR_DECIMALS));
return balance.lt(0) ? "0" : balance.toFixed();
}

function getValidators() {
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: "dontcare",
method: "validators",
params: [null],
}),
};
return fetch(config.nodeUrl, options).body.result;
}

function getBlock(blockId) {
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: "dontcare",
method: "block",
params: !!blockId
? {
block_id: blockId,
}
: {
finality: "final",
},
}),
};
return fetch(config.nodeUrl, options).body.result;
}

function lastestBlock() {
const lastBlock = getBlock();
const startBlock = getBlock(lastBlock.header.next_epoch_id);
const prevBlock = getBlock(lastBlock.header.epoch_id);
let prev_timestamp = Math.round((prevBlock.header.timestamp ?? 0) / 1e6);
let start_block_height = startBlock.header.height;
let start_timestamp = Math.round((startBlock.header.timestamp ?? 0) / 1e6);
let last_block_timestamp = Math.round(
(lastBlock.header.timestamp ?? 0) / 1e6
);

if (start_timestamp < new Date().getTime() - 48 * HOURS) {
//genesis or hard-fork
start_timestamp = new Date().getTime() - 6 * HOURS;
}
if (prev_timestamp < new Date().getTime() - 48 * HOURS) {
//genesis or hard-fork
prev_timestamp = new Date().getTime() - 12 * HOURS;
}

//const noPrevBloc = startBlock.header.height == prevBlock.header.height;
let length = startBlock.header.height - prevBlock.header.height,
duration_ms = 0,
advance;
let start_dtm, ends_dtm, duration_till_now_ms;
if (length === 0) {
//!prevBlock, genesis or hard-fork
length = 43200;
duration_ms = 12 * HOURS;
//estimated start & prev timestamps
advance =
Math.round(
Number(
((BigInt(lastBlock.header.height) - BigInt(this.start_block_height)) *
BigInt(1000000)) /
BigInt(this.length)
)
) / 1000000;
start_timestamp = last_block_timestamp - duration_ms * advance;
prev_timestamp = start_timestamp - duration_ms;
} else {
duration_ms = start_timestamp - prev_timestamp;
}

start_dtm = new Date(start_timestamp);
ends_dtm = new Date(start_timestamp + duration_ms);
duration_till_now_ms = last_block_timestamp - start_timestamp;

// update function
if (isValid(lastBlock.header.height) && isValid(start_block_height)) {
advance =
Math.round(
Big(lastBlock.header.height)
.minus(start_block_height)
.times(1000000)
.div(length)
.toNumber()
) / 1000000;
if (advance > 0.1) {
ends_dtm = new Date(
start_timestamp +
duration_till_now_ms +
duration_till_now_ms * (1 - advance)
);
}
}
return {
lastEpochDurationHours: duration_ms / HOURS,
hoursToEnd:
Math.round(
((start_timestamp + duration_ms - new Date().getTime()) / HOURS) * 100
) / 100,
};
}

function padNumber(n) {
if (n < 10) return `0${n}`;
return n.toString();
}
function queryFinishedTime(epochHeight) {
const nowValidator = getValidators();
let nowEpochHeight = nowValidator.epoch_height;

if (nowEpochHeight >= epochHeight) return null;

const { hoursToEnd, lastEpochDurationHours } = lastestBlock();
const BUFFER = 3; // 3 HOURs buffer
const durationHours =
hoursToEnd +
(epochHeight - nowEpochHeight - 1) * lastEpochDurationHours +
BUFFER;

if (durationHours) {
const finishedTime = new Date(new Date().getTime() + durationHours * HOURS);
return {
finishedTime: `${finishedTime.getFullYear()}/${padNumber(
finishedTime.getMonth() + 1
)}/${padNumber(finishedTime.getDate())} ${padNumber(
finishedTime.getHours()
)}:${padNumber(finishedTime.getMinutes())}:${padNumber(
finishedTime.getSeconds()
)}`,
durationHours: Math.floor(durationHours).toString(),
};
} else {
return {};
}
}

const account = Near.view(config.contractId, "get_account_details", {
account_id: accountId,
});

const finishedTime = queryFinishedTime(account.unstaked_available_epoch_height);

State.init({
tabName: "stake", // stake | unstake
page: "stake", // "stake" | "account"
nearBalance: "",
unstakeInfo: {},
});

const Main = styled.div`
Expand Down Expand Up @@ -343,15 +149,13 @@ function updateAccountInfo(callback) {
}, 500);
}

if (state.page === "stake") {
return (
function onLoad(data) {
State.update({ unstakeInfo: data });
}

const body =
state.page === "stake" ? (
<Main>
<Widget
src={`${config.ownerId}/widget/LiNEAR.Navigation`}
props={{
updatePage,
}}
/>
<Widget src={`${config.ownerId}/widget/LiNEAR.TitleAndDescription`} />
<Widget src={`${config.ownerId}/widget/LiNEAR.Apy`} />
<Widget
Expand Down Expand Up @@ -381,20 +185,32 @@ if (state.page === "stake") {
/>
)}
</Main>
);
} else {
return (
) : (
<Widget
src={`${config.ownerId}/widget/LiNEAR.Account`}
props={{
updatePage,
updateTabName,
config,
nearBalance,
account,
linearBalance,
finishedTime,
unstakeInfo: state.unstakeInfo,
}}
/>
);
}

return (
<Main>
<Widget
src={`${config.ownerId}/widget/LiNEAR.Data.Unstake`}
props={{ config, onLoad }}
/>
<Widget
src={`${config.ownerId}/widget/LiNEAR.Navigation`}
props={{
updatePage,
}}
/>
{body}
</Main>
);
25 changes: 10 additions & 15 deletions src/LiNEAR/Account.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,10 @@ const {
config,
nearBalance,
linearBalance,
account,
finishedTime,
unstakeInfo,
} = props;
if (!config) {
return "Component not be loaded. Missing `config` props";
return "Component cannot be loaded. Missing `config` props";
}

State.init({
Expand Down Expand Up @@ -165,18 +164,14 @@ const formattedLinearBalance =
? "-"
: Big(linearBalance).toFixed(5, BIG_ROUND_DOWN);

const finishedTime = unstakeInfo.endTime || {};

return (
<Main>
<Widget
src={`${config.ownerId}/widget/LiNEAR.Data`}
src={`${config.ownerId}/widget/LiNEAR.Data.Stake`}
props={{ config, onLoad }}
/>
<Widget
src={`${config.ownerId}/widget/LiNEAR.Navigation`}
props={{
updatePage,
}}
/>
<MyAccountTitle>My Account</MyAccountTitle>
<MyAccountContent>
<MyAccountCardWrapper>
Expand Down Expand Up @@ -249,15 +244,15 @@ return (
</MyAccountCardWrapper>
)}

{account &&
account.unstaked_balance &&
Big(account.unstaked_balance).gte(ONE_MICRO_NEAR) && (
{unstakeInfo &&
unstakeInfo.amount &&
Big(unstakeInfo.amount).gte(ONE_MICRO_NEAR) && (
<MyAccountCardGroupWrapper style={{ marginTop: "10px" }}>
<div>
<TokenValue>
<div>
{account.unstaked_balance
? Big(account.unstaked_balance).div(YOCTONEAR).toFixed(5)
{unstakeInfo.amount
? Big(unstakeInfo.amount).div(YOCTONEAR).toFixed(5)
: "-"}
</div>
<NearIcon />
Expand Down
File renamed without changes.
Loading