Skip to content

Commit

Permalink
Calculate the APR of staking dynamically
Browse files Browse the repository at this point in the history
  • Loading branch information
Thunnini committed Oct 16, 2020
1 parent 968d244 commit 8c9c1af
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 3 deletions.
31 changes: 31 additions & 0 deletions src/ui/hooks/use-inflation-info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useState, useEffect } from "react";
import { useFetch } from "./use-fetch";
import { Dec } from "@chainapsis/cosmosjs/common/decimal";

interface Result {
height: string;
result: string;
}

/**
* @param baseUrl Url of rest endpoint
*/
export const useInflationInfo = (baseUrl: string) => {
const [inflation, setInflation] = useState<Dec | undefined>();

const fetch = useFetch<Result>(baseUrl + "/minting/inflation", "get");

useEffect(() => {
if (fetch.data && fetch.data.result) {
const result = fetch.data.result;

setInflation(new Dec(result));
}
}, [fetch.data]);

return {
inflation,
refresh: fetch.refresh,
fetching: fetch.fetching
};
};
35 changes: 35 additions & 0 deletions src/ui/hooks/use-staking-pool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useState, useEffect } from "react";
import { useFetch } from "./use-fetch";

export interface StakingPool {
not_bonded_tokens: string;
bonded_tokens: string;
}

interface Result {
height: string;
result: StakingPool;
}

/**
* @param baseUrl Url of rest endpoint
*/
export const useStakingPool = (baseUrl: string) => {
const [pool, setPool] = useState<StakingPool | undefined>();

const fetch = useFetch<Result>(baseUrl + "/staking/pool", "get");

useEffect(() => {
if (fetch.data && fetch.data.result) {
const result = fetch.data.result;

setPool(result);
}
}, [fetch.data]);

return {
pool,
refresh: fetch.refresh,
fetching: fetch.fetching
};
};
30 changes: 30 additions & 0 deletions src/ui/hooks/use-supply-total.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useState, useEffect } from "react";
import { useFetch } from "./use-fetch";

interface Result {
height: string;
result: string;
}

/**
* @param baseUrl Url of rest endpoint
*/
export const useSupplyTotal = (baseUrl: string, denom: string) => {
const [result, setResult] = useState<string | undefined>();

const fetch = useFetch<Result>(baseUrl + `/supply/total/${denom}`, "get");

useEffect(() => {
if (fetch.data && fetch.data.result) {
const result = fetch.data.result;

setResult(result);
}
}, [fetch.data]);

return {
result,
refresh: fetch.refresh,
fetching: fetch.fetching
};
};
2 changes: 1 addition & 1 deletion src/ui/popup/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

"main.stake.message.pending-staking-reward": "Pending Staking Reward",
"main.stake.message.stake": "Stake",
"main.stake.message.earning": "Earn up to 7-11% per year",
"main.stake.message.earning": "Earn up to {apr}% per year",
"main.stake.button.claim-rewards": "Claim",
"main.stake.button.stake": "Stake",
"main.stake.tooltip.no-asset": "No token in your account. Deposit some tokens to stake.",
Expand Down
2 changes: 1 addition & 1 deletion src/ui/popup/languages/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

"main.stake.message.pending-staking-reward": "스테이킹 보상",
"main.stake.message.stake": "스테이킹",
"main.stake.message.earning": "연간 7~11%의 이자를 받으세요",
"main.stake.message.earning": "연간 {apr}%의 이자를 받으세요",
"main.stake.button.claim-rewards": "보상 받기",
"main.stake.button.stake": "스테이킹",
"main.stake.tooltip.no-asset": "계정에 자산이 없습니다. 자산을 입금해주세요.",
Expand Down
60 changes: 59 additions & 1 deletion src/ui/popup/pages/main/stake.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ import { useNotification } from "../../../components/notification";
import { useHistory } from "react-router";

import { FormattedMessage } from "react-intl";
import { useInflationInfo } from "../../../hooks/use-inflation-info";
import { useStakingPool } from "../../../hooks/use-staking-pool";
import { useSupplyTotal } from "../../../hooks/use-supply-total";
import { DecUtils } from "../../../../common/dec-utils";

export const StakeView: FunctionComponent = observer(() => {
const history = useHistory();
Expand All @@ -51,6 +55,45 @@ export const StakeView: FunctionComponent = observer(() => {

const notification = useNotification();

const inflation = useInflationInfo(chainStore.chainInfo.rest);
const stakingPool = useStakingPool(chainStore.chainInfo.rest);
const supply = useSupplyTotal(
chainStore.chainInfo.rest,
chainStore.chainInfo.stakeCurrency.coinMinimalDenom
);

const apr = useMemo(() => {
if (inflation.inflation && !inflation.fetching) {
if (
stakingPool.pool &&
!stakingPool.fetching &&
supply.result &&
!supply.fetching
) {
let dec = inflation.inflation.mulTruncate(DecUtils.getPrecisionDec(2));
const bondedToken = new Dec(stakingPool.pool.bonded_tokens);
const total = new Dec(supply.result);
if (total.gt(new Dec(0))) {
const stakingRatio = bondedToken.quo(new Dec(supply.result));

dec = dec.quo(stakingRatio);
}
return dec;
} else {
return inflation.inflation.mulTruncate(DecUtils.getPrecisionDec(2));
}
} else {
return undefined;
}
}, [
inflation.fetching,
inflation.inflation,
stakingPool.fetching,
stakingPool.pool,
supply.fetching,
supply.result
]);

const reward = useReward(
chainStore.chainInfo.rest,
accountStore.bech32Address,
Expand Down Expand Up @@ -243,7 +286,22 @@ export const StakeView: FunctionComponent = observer(() => {
styleStake.paragraphSub
)}
>
<FormattedMessage id="main.stake.message.earning" />
<FormattedMessage
id="main.stake.message.earning"
values={{
apr: (
<React.Fragment>
{apr ? (
DecUtils.trim(apr ? apr.toString(1) : "0")
) : (
<span>
<i className="fas fa-spinner fa-spin" />
</span>
)}
</React.Fragment>
)
}}
/>
</p>
</div>
<div style={{ flex: 1 }} />
Expand Down

0 comments on commit 8c9c1af

Please sign in to comment.