Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
 into main
  • Loading branch information
happylolonly committed May 29, 2024
2 parents 6729858 + d4b9b7c commit 53ac8e7
Show file tree
Hide file tree
Showing 20 changed files with 407 additions and 1 deletion.
1 change: 1 addition & 0 deletions front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@vercel/analytics": "^1.2.2",
"@vkruglikov/react-telegram-web-app": "^2.1.1",
"axios": "^1.5.0",
"bignumber.js": "^9.1.2",
"classnames": "^2.5.1",
"eslint-plugin-simple-import-sort": "^12.0.0",
"framer-motion": "^10.16.4",
Expand Down
3 changes: 3 additions & 0 deletions front/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const BASE_DENOM = "boot";

export const CYBER_GATEWAY = "https://gateway.ipfs.cybernode.ai";
10 changes: 9 additions & 1 deletion front/src/pages/Main/Passport/Passport.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { Citizenship } from "@/types";
import React from "react";
import Balances from "./ui/Balances/Balances";
import Avatar from "./ui/Avatar/Avatar";

function Passport({ passport }: { passport: Citizenship }) {
const address = passport?.owner;
const cid = passport?.extension.avatar;

return (
<div>
{JSON.stringify(passport)}

<Avatar cid={cid} />

<Balances address={address} />

{/* <MusicalAddress address={passport.owner} /> */}
</div>
);
Expand Down
10 changes: 10 additions & 0 deletions front/src/pages/Main/Passport/ui/Avatar/Avatar.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
$size: 130px;

.wrapper {

img {
width: $size;
height: $size;
border-radius: 50%;
}
}
15 changes: 15 additions & 0 deletions front/src/pages/Main/Passport/ui/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { CYBER_GATEWAY } from '@/constants';
import styles from './Avatar.module.scss';

function Avatar({ cid }: {cid: string}) {

const urlCid = `${CYBER_GATEWAY}/ipfs/${cid}`;

return (
<div className={styles.wrapper}>
<img src={urlCid} alt="avatar" />
</div>
);
}

export default Avatar;
33 changes: 33 additions & 0 deletions front/src/pages/Main/Passport/ui/Balances/Balances.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
$size-item-text: 16px;

.wrapper {
display: grid;
gap: 20px;
}

.wrapperItem {
display: flex;
align-items: center;
justify-content: space-between;

.denom {
font-size: $size-item-text;
text-transform: uppercase;
}


.amount {
display: flex;
align-items: center;
gap: 10px;

span {
font-size: $size-item-text;
}

img {
width: 20px;
height: 20px;
}
}
}
45 changes: 45 additions & 0 deletions front/src/pages/Main/Passport/ui/Balances/Balances.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import useQueryGetAllBalances from "./api/useQueryGetAllBalances";
import { Denom } from "./type";
import { DenomListKey, configDenom } from "./utils/configDenom";
import styles from "./Balances.module.scss";
import { formatNumber } from "./utils/formatNumber";
import TitleItem from "../TitleItem/TitleItem";

function BalancesItem({
amount,
denom,
}: {
amount?: any;
denom: DenomListKey;
}) {
return (
<div className={styles.wrapperItem}>
<span className={styles.denom}>{configDenom[denom].denom}</span>
<div className={styles.amount}>
<span>{formatNumber(amount || 0)}</span>
<img src={configDenom[denom].img} alt={denom} />
</div>
</div>
);
}

function Balances({ address }: { address: string }) {
const data = useQueryGetAllBalances({ address });

if (data) {
const renderItem = Object.keys(Denom).map((key: DenomListKey) => {
const { amount } = data.find((item) => item.denom === key);
return <BalancesItem key={key} denom={key} amount={amount} />;
});

return (
<TitleItem title="Balances">
<div className={styles.wrapper}>{renderItem}</div>
</TitleItem>
);
}

return null;
}

export default Balances;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { CyberClient } from "@cybercongress/cyber-js";
import { DelegationResponse } from "cosmjs-types/cosmos/staking/v1beta1/staking";

export const getDelegatorDelegations = async (
client: CyberClient,
addressBech32: string
): Promise<DelegationResponse[]> => {
let nextKey;
const delegationData: DelegationResponse[] = [];

let done = false;
while (!done) {
// eslint-disable-next-line no-await-in-loop
const responsedelegatorDelegations = await client.delegatorDelegations(
addressBech32,
nextKey
);

delegationData.push(...responsedelegatorDelegations.delegationResponses);

const key = responsedelegatorDelegations?.pagination?.nextKey;

if (key) {
nextKey = key;
} else {
done = true;
}
}

return delegationData;
};
127 changes: 127 additions & 0 deletions front/src/pages/Main/Passport/ui/Balances/api/useGetBalance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/* eslint-disable no-restricted-syntax */
import { Decimal } from "@cosmjs/math";
import BigNumber from "bignumber.js";
import { useQuery } from "@tanstack/react-query";
import { useQueryClient } from "@/queryClient";
import { BASE_DENOM } from "@/constants";
import { getDelegatorDelegations } from "./getDelegatorDelegations";

const initValue = {
denom: BASE_DENOM,
amount: "0",
};

export const initValueMainToken = {
liquid: { ...initValue },
frozen: { ...initValue },
melting: { ...initValue },
growth: { ...initValue },
total: { ...initValue },
};

const initValueResponseFunc = (denom = "", amount = 0) => {
return { denom, amount };
};

const getDelegationsAmount = (data) => {
let delegationsAmount = new BigNumber(0);
if (data.length) {
data.forEach((itemDelegation) => {
delegationsAmount = delegationsAmount.plus(itemDelegation.balance.amount);
});
}
return initValueResponseFunc(BASE_DENOM, delegationsAmount.toNumber());
};

const getUnbondingAmount = (data) => {
let unbondingAmount = new BigNumber(0);
const { unbondingResponses } = data;
if (unbondingResponses && Object.keys(unbondingResponses).length > 0) {
unbondingResponses.forEach((unbond) => {
unbond.entries.forEach((entry) => {
unbondingAmount = unbondingAmount.plus(entry.balance);
});
});
}
return initValueResponseFunc(BASE_DENOM, unbondingAmount.toNumber());
};

const getRewardsAmount = (data) => {
let rewardsAmount = new BigNumber(0);
const { total } = data;
if (total && total.length > 0) {
const [{ amount }] = total;
rewardsAmount = rewardsAmount.plus(
Decimal.fromAtomics(amount, 18).floor().toString()
);
}
return initValueResponseFunc(BASE_DENOM, rewardsAmount.toNumber());
};

export const useGetBalance = (addressBech32: string) => {
const client = useQueryClient();

try {
const { data, isFetching } = useQuery({
queryKey: ["getBalance", addressBech32],
queryFn: async () => {
const responsegetBalance = await client.getBalance(
addressBech32,
BASE_DENOM
);

const responsedelegatorDelegations = await getDelegatorDelegations(
client,
addressBech32
);

const delegationsAmount = getDelegationsAmount(
responsedelegatorDelegations
);

const responsedelegatorUnbondingDelegations =
await client.delegatorUnbondingDelegations(addressBech32);

const unbondingAmount = getUnbondingAmount(
responsedelegatorUnbondingDelegations
);

const responsedelegationTotalRewards =
await client.delegationTotalRewards(addressBech32);

const rewardsAmount = getRewardsAmount(responsedelegationTotalRewards);

const resultBalance = {
liquid: responsegetBalance,
frozen: delegationsAmount,
melting: unbondingAmount,
growth: rewardsAmount,
};

const total = Object.values(resultBalance).reduce((acc, item) => {
return new BigNumber(acc).plus(item.amount).toString();
}, 0);

return {
...resultBalance,
total: {
denom: BASE_DENOM,
amount: total,
},
};
},
enabled: Boolean(client && addressBech32),
});

if (data && data !== null && !isFetching) {
return data;
}

return undefined;
} catch (error) {
console.log(`error`, error);
const tempObj = { ...initValueMainToken };
delete tempObj.total;
return { ...tempObj };
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useQueryClient } from "@/queryClient";
import { useQuery } from "@tanstack/react-query";

const balanceFetcher = (options, client) => {
const { address } = options;

if (!client || address === null) {
return null;
}

return client.getAllBalances(address);
};

const useQueryGetAllBalances = (options) => {
const queryClient = useQueryClient();
const { address } = options;

const { data } = useQuery({
queryKey: ["getAllBalances", address],
queryFn: () => balanceFetcher(options, queryClient),
enabled: Boolean(queryClient && address),
});

return data;
};

export default useQueryGetAllBalances;
5 changes: 5 additions & 0 deletions front/src/pages/Main/Passport/ui/Balances/assets/hydrogen.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions front/src/pages/Main/Passport/ui/Balances/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum Denom {
"boot" = "BOOT",
"hydrogen" = "H",
"milliampere" = "A",
"millivolt" = "V",
}
40 changes: 40 additions & 0 deletions front/src/pages/Main/Passport/ui/Balances/utils/configDenom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import boot from "../assets/large-green.png";
import milliampere from "../assets/light.png";
import hydrogen from "../assets/hydrogen.svg";
import millivolt from "../assets/lightning.png";
import { Denom } from "../type";

type DenomItem = {
denom: string;
coinDecimals: number;
img: string;
};

export type DenomListKey = keyof typeof Denom;

type DenomList = {
[key in DenomListKey]: DenomItem;
};

export const configDenom: DenomList = {
boot: {
denom: "BOOT",
img: boot,
coinDecimals: 0,
},
hydrogen: {
denom: "H",
img: hydrogen,
coinDecimals: 0,
},
milliampere: {
denom: "A",
img: milliampere,
coinDecimals: 3,
},
millivolt: {
denom: "V",
img: millivolt,
coinDecimals: 3,
},
};
Loading

0 comments on commit 53ac8e7

Please sign in to comment.