From b25582994d2c7bb28113790c10973cd424f7a96e Mon Sep 17 00:00:00 2001 From: infra1515 Date: Thu, 6 Oct 2022 21:22:47 +0300 Subject: [PATCH 1/7] added sample env files for deployment --- sample_configs/aura-pool/.env-big-dipper-2 | 8 ++++++++ sample_configs/mainnet/.env-big-dipper-2 | 8 ++++++++ sample_configs/private-testnet/.env-big-dipper-2 | 8 ++++++++ sample_configs/public-testnet/.env-big-dipper-2 | 0 4 files changed, 24 insertions(+) create mode 100644 sample_configs/aura-pool/.env-big-dipper-2 create mode 100644 sample_configs/mainnet/.env-big-dipper-2 create mode 100644 sample_configs/private-testnet/.env-big-dipper-2 create mode 100644 sample_configs/public-testnet/.env-big-dipper-2 diff --git a/sample_configs/aura-pool/.env-big-dipper-2 b/sample_configs/aura-pool/.env-big-dipper-2 new file mode 100644 index 0000000000..9cef1849df --- /dev/null +++ b/sample_configs/aura-pool/.env-big-dipper-2 @@ -0,0 +1,8 @@ +NEXT_PUBLIC_GRAPHQL_URL=http://34.68.222.131:8080/v1/graphql +NEXT_PUBLIC_GRAPHQL_WS=wss://34.68.222.131/v1/graphql +NODE_ENV=production +PORT=3000 +NEXT_PUBLIC_URL=http://34.68.222.131:3000 +NEXT_PUBLIC_WS_CHAIN_URL=ws://34.121.218.76:26657/websocket +NEXT_PUBLIC_CHAIN_STATUS=testnet +LOGGING_DRIVER=gcplogs \ No newline at end of file diff --git a/sample_configs/mainnet/.env-big-dipper-2 b/sample_configs/mainnet/.env-big-dipper-2 new file mode 100644 index 0000000000..db8e9b3dd2 --- /dev/null +++ b/sample_configs/mainnet/.env-big-dipper-2 @@ -0,0 +1,8 @@ +NEXT_PUBLIC_GRAPHQL_URL=https://explorer-gql.cudos.org/v1/graphql +NEXT_PUBLIC_GRAPHQL_WS=wss://explorer-gql.cudos.org/v1/graphql +NODE_ENV=production +PORT=3000 +NEXT_PUBLIC_URL=https://explorer.cudos.org +NEXT_PUBLIC_WS_CHAIN_URL=wss://mainnet-full-node-01.gcp.service.cudo.org:36657/websocket +NEXT_PUBLIC_CHAIN_STATUS=mainnet +LOGGING_DRIVER=gcplogs \ No newline at end of file diff --git a/sample_configs/private-testnet/.env-big-dipper-2 b/sample_configs/private-testnet/.env-big-dipper-2 new file mode 100644 index 0000000000..69b043d1f2 --- /dev/null +++ b/sample_configs/private-testnet/.env-big-dipper-2 @@ -0,0 +1,8 @@ +NEXT_PUBLIC_GRAPHQL_URL=https://explorer-gql.private-testnet.cudos.org/v1/graphql +NEXT_PUBLIC_GRAPHQL_WS=wss://explorer-gql.private-testnet.cudos.org/v1/graphql +NODE_ENV=production +PORT=3000 +NEXT_PUBLIC_URL=https://explorer.private-testnet.cudos.org/ +NEXT_PUBLIC_WS_CHAIN_URL=wss://sentry-01.hosts.private-testnet.cudos.org:36657/websocket +NEXT_PUBLIC_CHAIN_STATUS=testnet +LOGGING_DRIVER=gcplogs \ No newline at end of file diff --git a/sample_configs/public-testnet/.env-big-dipper-2 b/sample_configs/public-testnet/.env-big-dipper-2 new file mode 100644 index 0000000000..e69de29bb2 From a04a6147c231f48ec8c7cf3efea01a7ebdbd8981 Mon Sep 17 00:00:00 2001 From: Tugay Emin Date: Thu, 20 Oct 2022 20:41:29 +0300 Subject: [PATCH 2/7] display user cw20 balances --- public/locales/en/accounts.json | 3 +- src/graphql/cw20_tokens.ts | 34 ++++++++ .../components/desktop/index.tsx | 84 +++++++++++++++++++ .../components/desktop/utils.ts | 20 +++++ .../cw20_token_balances/components/index.ts | 7 ++ .../components/mobile/index.tsx | 73 ++++++++++++++++ .../components/mobile/styles.ts | 51 +++++++++++ .../components/cw20_token_balances/index.tsx | 69 +++++++++++++++ .../components/cw20_token_balances/styles.tsx | 26 ++++++ src/screens/account_details/hooks.ts | 6 ++ src/screens/account_details/index.tsx | 5 ++ src/screens/account_details/styles.ts | 5 ++ src/screens/account_details/types.ts | 26 ++++++ src/screens/account_details/utils.ts | 37 ++++++++ 14 files changed, 445 insertions(+), 1 deletion(-) create mode 100644 src/graphql/cw20_tokens.ts create mode 100644 src/screens/account_details/components/cw20_token_balances/components/desktop/index.tsx create mode 100644 src/screens/account_details/components/cw20_token_balances/components/desktop/utils.ts create mode 100644 src/screens/account_details/components/cw20_token_balances/components/index.ts create mode 100644 src/screens/account_details/components/cw20_token_balances/components/mobile/index.tsx create mode 100644 src/screens/account_details/components/cw20_token_balances/components/mobile/styles.ts create mode 100644 src/screens/account_details/components/cw20_token_balances/index.tsx create mode 100644 src/screens/account_details/components/cw20_token_balances/styles.tsx diff --git a/public/locales/en/accounts.json b/public/locales/en/accounts.json index 4fbb28a813..171978abc7 100644 --- a/public/locales/en/accounts.json +++ b/public/locales/en/accounts.json @@ -39,5 +39,6 @@ "label": "Label", "codeId": "Code Id", "instaBlock": "Instantiated At Block", - "collateralTransactions": "Collateral Transactions" + "collateralTransactions": "Collateral Transactions", + "cw20tokens": "CW20 Tokens" } diff --git a/src/graphql/cw20_tokens.ts b/src/graphql/cw20_tokens.ts new file mode 100644 index 0000000000..3857f59be0 --- /dev/null +++ b/src/graphql/cw20_tokens.ts @@ -0,0 +1,34 @@ +export const Cw20TokenBalancesDocument = /* GraphQL */` +query Cw20TokenBalances($address: String!) { + cw20token_balance(where: {address: {_eq: $address}}) { + balance + cw20token_info { + address + name + symbol + decimals + logo + } + } +} +`; + +// query cw20_token_info { +// cw20token_info_by_pk(address: "") { +// circulating_supply +// code_id +// decimals +// description +// logo +// marketing_admin +// max_supply +// minter +// name +// project_url +// symbol +// balances { +// address +// balance +// } +// } +// } diff --git a/src/screens/account_details/components/cw20_token_balances/components/desktop/index.tsx b/src/screens/account_details/components/cw20_token_balances/components/desktop/index.tsx new file mode 100644 index 0000000000..623bfbff2a --- /dev/null +++ b/src/screens/account_details/components/cw20_token_balances/components/desktop/index.tsx @@ -0,0 +1,84 @@ +import React from 'react'; +import classnames from 'classnames'; +import useTranslation from 'next-translate/useTranslation'; +import { + Table, + TableHead, + TableRow, + TableCell, + TableBody, +} from '@material-ui/core'; +import { + AvatarName, +} from '@components'; +import { formatNumber } from '@utils/format_token'; +import { Cw20TokenBalance } from '@src/screens/account_details/types'; +import { getMiddleEllipsis } from '@utils/get_middle_ellipsis'; +import { columns } from './utils'; + +const Desktop: React.FC<{ + className?: string; + balances?: Cw20TokenBalance[] +}> = ({ + className, + balances, +}) => { + const { t } = useTranslation('accounts'); + const balancesFormatted = balances.map((b) => { + const balance = formatNumber(b.balance.toString(), b.exponent); + return ({ + token: ( + + ), + balance: `${balance} ${b.denom.toUpperCase()}`, + address: getMiddleEllipsis(b.tokenAddress, { + beginning: 15, ending: 10, + }), + }); + }); + + return ( +
+ + + + {columns.map((column) => { + return ( + + {t(column.key)} + + ); + })} + + + + {balancesFormatted.map((b, i) => ( + + {columns.map((column) => { + return ( + + {b[column.key]} + + ); + })} + + ))} + +
+
+ ); +}; + +export default Desktop; diff --git a/src/screens/account_details/components/cw20_token_balances/components/desktop/utils.ts b/src/screens/account_details/components/cw20_token_balances/components/desktop/utils.ts new file mode 100644 index 0000000000..2dcf388bba --- /dev/null +++ b/src/screens/account_details/components/cw20_token_balances/components/desktop/utils.ts @@ -0,0 +1,20 @@ +export const columns:{ + key: string; + align?: 'left' | 'center' | 'right' | 'justify' | 'inherit'; + width: number; +}[] = [ + { + key: 'token', + width: 40, + }, + { + key: 'balance', + width: 33, + }, + { + key: 'address', + width: 33, + align: 'right', + + }, +]; diff --git a/src/screens/account_details/components/cw20_token_balances/components/index.ts b/src/screens/account_details/components/cw20_token_balances/components/index.ts new file mode 100644 index 0000000000..3f1746a986 --- /dev/null +++ b/src/screens/account_details/components/cw20_token_balances/components/index.ts @@ -0,0 +1,7 @@ +import Desktop from './desktop'; +import Mobile from './mobile'; + +export { + Desktop, + Mobile, +}; diff --git a/src/screens/account_details/components/cw20_token_balances/components/mobile/index.tsx b/src/screens/account_details/components/cw20_token_balances/components/mobile/index.tsx new file mode 100644 index 0000000000..289f6c4160 --- /dev/null +++ b/src/screens/account_details/components/cw20_token_balances/components/mobile/index.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import classnames from 'classnames'; +import useTranslation from 'next-translate/useTranslation'; +import { + Divider, + Typography, +} from '@material-ui/core'; +import { AvatarName } from '@components'; +import { formatNumber } from '@utils/format_token'; +import { Cw20TokenBalance } from '@src/screens/account_details/types'; +import { getMiddleEllipsis } from '@src/utils/get_middle_ellipsis'; +import { useStyles } from './styles'; + +const Mobile: React.FC<{ + className?: string; + balances?: Cw20TokenBalance[] +}> = ({ + className, + balances, +}) => { + const classes = useStyles(); + const { t } = useTranslation('accounts'); + + return ( +
+ {balances.map((b, i) => { + return ( + +
+
+ + {t('token')} + + +
+
+
+ + {t('balance')} + + + {formatNumber(b.balance.toString(), b.exponent)} + {' '} + {b.denom.toUpperCase()} + +
+
+
+
+ + {t('address')} + + + {getMiddleEllipsis(b.tokenAddress, { + beginning: 15, ending: 10, + })} + +
+
+
+ {i !== balances.length - 1 && } +
+ ); + })} +
+ ); +}; + +export default Mobile; diff --git a/src/screens/account_details/components/cw20_token_balances/components/mobile/styles.ts b/src/screens/account_details/components/cw20_token_balances/components/mobile/styles.ts new file mode 100644 index 0000000000..033ec3b23f --- /dev/null +++ b/src/screens/account_details/components/cw20_token_balances/components/mobile/styles.ts @@ -0,0 +1,51 @@ +import { makeStyles } from '@material-ui/core/styles'; + +export const useStyles = () => { + const styles = makeStyles( + (theme) => { + return ({ + list: { + margin: theme.spacing(2, 0), + }, + item: { + marginBottom: theme.spacing(2), + '& .label': { + marginBottom: theme.spacing(1), + color: theme.palette.custom.fonts.fontThree, + }, + '& p.value': { + color: theme.palette.custom.fonts.fontTwo, + '&.unknown': { + color: theme.palette.custom.condition.zero, + }, + '&.unbonded': { + color: theme.palette.custom.condition.zero, + }, + '&.active': { + color: theme.palette.custom.condition.one, + }, + '&.jailed': { + color: theme.palette.custom.condition.two, + }, + '&.unbonding': { + color: theme.palette.custom.condition.three, + }, + }, + '& a': { + color: theme.palette.custom.fonts.highlight, + }, + }, + flex: { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-start', + '& > div': { + width: '50%', + }, + }, + }); + }, + )(); + + return styles; +}; diff --git a/src/screens/account_details/components/cw20_token_balances/index.tsx b/src/screens/account_details/components/cw20_token_balances/index.tsx new file mode 100644 index 0000000000..1553522659 --- /dev/null +++ b/src/screens/account_details/components/cw20_token_balances/index.tsx @@ -0,0 +1,69 @@ +import React from 'react'; +import classnames from 'classnames'; +import dynamic from 'next/dynamic'; +import { + usePagination, + useScreenSize, +} from '@hooks'; +import { + Pagination, + // Loading, + Box, +} from '@components'; +import { Typography } from '@material-ui/core'; +import useTranslation from 'next-translate/useTranslation'; +import { useStyles } from './styles'; +import { Cw20TokenBalance } from '../../types'; + +const Desktop = dynamic(() => import('./components/desktop')); +const Mobile = dynamic(() => import('./components/mobile')); + +const Cw20TokenBalances: React.FC<{ + balances: Cw20TokenBalance[], + loading?: boolean // todo implement loading sth +} & ComponentDefault> = (props) => { + if (!props.balances?.length) { + return null; + } + + const { t } = useTranslation('accounts'); + const { isDesktop } = useScreenSize(); + const classes = useStyles(); + const { + page, + rowsPerPage, + handleChangePage, + handleChangeRowsPerPage, + sliceItems, + } = usePagination({}); + + const paginatedBalances = sliceItems(props.balances); + + let component = null; + if (isDesktop) { + component = ; + } else { + component = ; + } + + return ( + + + {t('cw20tokens')} + +
+ {component} + +
+
+ ); +}; + +export default Cw20TokenBalances; diff --git a/src/screens/account_details/components/cw20_token_balances/styles.tsx b/src/screens/account_details/components/cw20_token_balances/styles.tsx new file mode 100644 index 0000000000..b41ae1afc0 --- /dev/null +++ b/src/screens/account_details/components/cw20_token_balances/styles.tsx @@ -0,0 +1,26 @@ +import { makeStyles } from '@material-ui/core/styles'; + +export const useStyles = () => { + const styles = makeStyles( + (theme) => { + return ({ + paginate: { + marginTop: theme.spacing(3), + }, + mobile: { + [theme.breakpoints.up('lg')]: { + display: 'none', + }, + }, + desktop: { + display: 'none', + [theme.breakpoints.up('lg')]: { + display: 'flex', + }, + }, + }); + }, + )(); + + return styles; +}; diff --git a/src/screens/account_details/hooks.ts b/src/screens/account_details/hooks.ts index 0f148b9037..40678e556c 100644 --- a/src/screens/account_details/hooks.ts +++ b/src/screens/account_details/hooks.ts @@ -19,6 +19,7 @@ import { fetchRewards, fetchUnbondingBalance, fetchCosmWasmInstantiation, + fetchCW20TokenBalances, } from './utils'; const defaultTokenUnit: TokenUnit = { @@ -63,6 +64,7 @@ const initialState: AccountDetailState = { }, }, tab: 0, + cw20TokenBalances: [], }; export const useAccountDetails = () => { @@ -128,6 +130,7 @@ export const useAccountDetails = () => { fetchUnbondingBalance(address), fetchRewards(address), fetchCosmWasmInstantiation(address), + fetchCW20TokenBalances(address), ]; const [ commission, @@ -136,6 +139,7 @@ export const useAccountDetails = () => { unbonding, rewards, cosmWasmInstantiation, + cw20TokenBalances, ] = await Promise.allSettled(promises); const formattedRawData: any = {}; @@ -144,6 +148,7 @@ export const useAccountDetails = () => { formattedRawData.delegationBalance = R.pathOr([], ['value', 'delegationBalance'], delegation); formattedRawData.unbondingBalance = R.pathOr([], ['value', 'unbondingBalance'], unbonding); formattedRawData.delegationRewards = R.pathOr([], ['value', 'delegationRewards'], rewards); + formattedRawData.cw20TokenBalances = R.pathOr([], ['value'], cw20TokenBalances); handleSetState(formatAllBalance(formattedRawData)); const rawData: any = {}; @@ -299,6 +304,7 @@ export const useAccountDetails = () => { formatOtherTokens(); stateChange.otherTokens = formatOtherTokens(); + stateChange.cw20TokenBalances = data.cw20TokenBalances; return stateChange; }; diff --git a/src/screens/account_details/index.tsx b/src/screens/account_details/index.tsx index 7e5843be52..e6a0fd80a5 100644 --- a/src/screens/account_details/index.tsx +++ b/src/screens/account_details/index.tsx @@ -22,6 +22,7 @@ import { SimpleBalance, } from './components'; import { useAccountDetails } from './hooks'; +import Cw20TokenBalances from './components/cw20_token_balances'; const AccountDetails = () => { const { t } = useTranslation('accounts'); @@ -115,6 +116,10 @@ const AccountDetails = () => { className={classes.otherTokens} otherTokens={state.otherTokens} /> + {!isSmartContract && ( { // gridColumn: '1 / 3', }, }, + cw20tokenBalances: { + [theme.breakpoints.up('lg')]: { + // gridColumn: '1 / 3', + }, + }, overview: { [theme.breakpoints.up('lg')]: { // gridColumn: '1 / 3', diff --git a/src/screens/account_details/types.ts b/src/screens/account_details/types.ts index 76f0aca447..743dd99fea 100644 --- a/src/screens/account_details/types.ts +++ b/src/screens/account_details/types.ts @@ -33,6 +33,31 @@ export type CosmwasmType = { transaction: any } +export type Cw20TokenBalance = { + tokenAddress: string, + name: string + denom: string, + exponent: number, + logo: string, + balance: number +} +// todo +// export type Cw20TokenInfo = { +// address: string, +// name: string, +// denom: string, +// logo: string, +// exponent: number, +// circulatingSupply: number, +// maxSupply: number, +// minterAddress: string, +// projectUrl: string, +// holders: { +// address: string, +// balance: number +// }[] +// } + export type AccountDetailState = { loading: boolean; exists: boolean; @@ -46,4 +71,5 @@ export type AccountDetailState = { rewards: RewardsType; cosmwasm: CosmwasmType; tab: number; + cw20TokenBalances: Cw20TokenBalance[]; } diff --git a/src/screens/account_details/utils.ts b/src/screens/account_details/utils.ts index 19a31a9276..1947eff5ef 100644 --- a/src/screens/account_details/utils.ts +++ b/src/screens/account_details/utils.ts @@ -13,6 +13,7 @@ import { import { CosmWasmInstantiateDocument, } from '@graphql/cosmwasm'; +import { Cw20TokenBalancesDocument } from '@src/graphql/cw20_tokens'; export const fetchCommission = async (address: string) => { const defaultReturnValue = { @@ -147,3 +148,39 @@ export const fetchCosmWasmInstantiation = async (address: string) => { return defaultReturnValue; } }; + +export const fetchCW20TokenBalances = async (address: string) => { + const defaultReturnValue = { + cw20TokenBalance: [{ + balance: '0', + cw20tokenInfo: { + address: '', + name: '', + logo: '', + symbol: '', + }, + }], + }; + try { + const { data } = await axios.post(process.env.NEXT_PUBLIC_GRAPHQL_URL, { + variables: { + address, + }, + query: Cw20TokenBalancesDocument, + }); + const balances = R.pathOr(defaultReturnValue, ['data'], data); + return balances.cw20token_balance.map((b) => { + const info = b.cw20token_info; + return { + tokenAddress: info.address, + name: info.name, + denom: info.symbol, + exponent: info.decimals, + logo: info.logo, + balance: b.balance, + }; + }); + } catch (error) { + return defaultReturnValue; + } +}; From 504f0e3f39f778be08fd1b89d37416b7e18fc9cb Mon Sep 17 00:00:00 2001 From: Tugay Emin Date: Thu, 20 Oct 2022 20:41:57 +0300 Subject: [PATCH 3/7] implement cw20 token overview --- public/locales/en/accounts.json | 10 ++- src/graphql/cw20_tokens.ts | 32 ++++----- .../components/cw20_token_balances/index.tsx | 3 +- .../components/cw20_token_overview/index.tsx | 66 ++++++++++++++++++ src/screens/account_details/hooks.ts | 11 +++ src/screens/account_details/index.tsx | 67 +++++++++++++------ src/screens/account_details/styles.ts | 13 ++-- src/screens/account_details/types.ts | 27 +++----- src/screens/account_details/utils.ts | 42 +++++++++++- 9 files changed, 206 insertions(+), 65 deletions(-) create mode 100644 src/screens/account_details/components/cw20_token_overview/index.tsx diff --git a/public/locales/en/accounts.json b/public/locales/en/accounts.json index 171978abc7..a5c2fa5964 100644 --- a/public/locales/en/accounts.json +++ b/public/locales/en/accounts.json @@ -40,5 +40,13 @@ "codeId": "Code Id", "instaBlock": "Instantiated At Block", "collateralTransactions": "Collateral Transactions", - "cw20tokens": "CW20 Tokens" + "cw20tokens": "CW20 Tokens", + "cw20TokenDetails": "CW20 Token Details", + "name": "Name", + "denom": "Denom", + "exponent": "Exponent", + "circulatingSupply": "Circulating Supply", + "minter": "Minter", + "maxSupply": "Maximum Supply", + "projectUrl": "Project URL" } diff --git a/src/graphql/cw20_tokens.ts b/src/graphql/cw20_tokens.ts index 3857f59be0..7a4eee90c1 100644 --- a/src/graphql/cw20_tokens.ts +++ b/src/graphql/cw20_tokens.ts @@ -13,22 +13,16 @@ query Cw20TokenBalances($address: String!) { } `; -// query cw20_token_info { -// cw20token_info_by_pk(address: "") { -// circulating_supply -// code_id -// decimals -// description -// logo -// marketing_admin -// max_supply -// minter -// name -// project_url -// symbol -// balances { -// address -// balance -// } -// } -// } +export const Cw20TokenInfoDocument = /* GraphQL */` +query Cw20TokenInfo($address: String!) { + cw20token_info_by_pk(address: $address) { + circulating_supply + decimals + max_supply + minter + name + project_url + symbol + } +} +`; diff --git a/src/screens/account_details/components/cw20_token_balances/index.tsx b/src/screens/account_details/components/cw20_token_balances/index.tsx index 1553522659..436ccfa903 100644 --- a/src/screens/account_details/components/cw20_token_balances/index.tsx +++ b/src/screens/account_details/components/cw20_token_balances/index.tsx @@ -7,7 +7,6 @@ import { } from '@hooks'; import { Pagination, - // Loading, Box, } from '@components'; import { Typography } from '@material-ui/core'; @@ -20,7 +19,7 @@ const Mobile = dynamic(() => import('./components/mobile')); const Cw20TokenBalances: React.FC<{ balances: Cw20TokenBalance[], - loading?: boolean // todo implement loading sth + loading?: boolean } & ComponentDefault> = (props) => { if (!props.balances?.length) { return null; diff --git a/src/screens/account_details/components/cw20_token_overview/index.tsx b/src/screens/account_details/components/cw20_token_overview/index.tsx new file mode 100644 index 0000000000..393f8c0414 --- /dev/null +++ b/src/screens/account_details/components/cw20_token_overview/index.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import classnames from 'classnames'; +import { BoxDetails } from '@components'; +import useTranslation from 'next-translate/useTranslation'; +import { Cw20TokenInfo } from '../../types'; + +const Cw20TokenOverview: React.FC<{ + tokenInfo: Cw20TokenInfo, + loading?: boolean +} & ComponentDefault> = (props) => { + if (props.tokenInfo.name === '') { + return null; + } + + const { t } = useTranslation('accounts'); + + const details = [ + { + label: t('name'), + detail: props.tokenInfo.name, + }, + { + label: t('denom'), + detail: props.tokenInfo.denom, + }, + { + label: t('exponent'), + detail: props.tokenInfo.exponent, + }, + { + label: t('circulatingSupply'), + detail: props.tokenInfo.circulatingSupply, + }, + ]; + + if (props.tokenInfo.minterAddress !== '') { + details.push({ + label: t('minter'), + detail: props.tokenInfo.minterAddress, + }); + } + + if (props.tokenInfo.maxSupply) { + details.push({ + label: t('maxSupply'), + detail: props.tokenInfo.maxSupply, + }); + } + + if (props.tokenInfo.projectUrl !== '') { + details.push({ + label: t('projectUrl'), + detail: props.tokenInfo.projectUrl, + }); + } + + return ( + + ); +}; + +export default Cw20TokenOverview; diff --git a/src/screens/account_details/hooks.ts b/src/screens/account_details/hooks.ts index 40678e556c..ffb9e72648 100644 --- a/src/screens/account_details/hooks.ts +++ b/src/screens/account_details/hooks.ts @@ -20,6 +20,7 @@ import { fetchUnbondingBalance, fetchCosmWasmInstantiation, fetchCW20TokenBalances, + fetchCW20TokenInfo, } from './utils'; const defaultTokenUnit: TokenUnit = { @@ -65,6 +66,13 @@ const initialState: AccountDetailState = { }, tab: 0, cw20TokenBalances: [], + cw20TokenInfo: { + name: '', + denom: '', + logo: '', + exponent: 0, + circulatingSupply: 0, + }, }; export const useAccountDetails = () => { @@ -131,6 +139,7 @@ export const useAccountDetails = () => { fetchRewards(address), fetchCosmWasmInstantiation(address), fetchCW20TokenBalances(address), + fetchCW20TokenInfo(address), ]; const [ commission, @@ -140,6 +149,7 @@ export const useAccountDetails = () => { rewards, cosmWasmInstantiation, cw20TokenBalances, + cw20TokenInfo, ] = await Promise.allSettled(promises); const formattedRawData: any = {}; @@ -153,6 +163,7 @@ export const useAccountDetails = () => { const rawData: any = {}; rawData.cosmwasm = R.pathOr([], ['value'], cosmWasmInstantiation); + rawData.cw20TokenInfo = R.pathOr([], ['value'], cw20TokenInfo); handleSetState(rawData); }; diff --git a/src/screens/account_details/index.tsx b/src/screens/account_details/index.tsx index e6a0fd80a5..46ffff14b8 100644 --- a/src/screens/account_details/index.tsx +++ b/src/screens/account_details/index.tsx @@ -23,6 +23,7 @@ import { } from './components'; import { useAccountDetails } from './hooks'; import Cw20TokenBalances from './components/cw20_token_balances'; +import Cw20TokenOverview from './components/cw20_token_overview'; const AccountDetails = () => { const { t } = useTranslation('accounts'); @@ -33,6 +34,45 @@ const AccountDetails = () => { } = useAccountDetails(); const isSmartContract = state.cosmwasm.result_contract_address === state.overview.address; + const isCw20Token = state.cw20TokenInfo.name && state.cw20TokenInfo.name !== ''; + + let title = ''; + if (isCw20Token) { + title = t('cw20TokenDetails'); + } else if (isSmartContract) { + title = t('smartContractDetails'); + } else { + title = t('accountDetails'); + } + + let overview; + if (isCw20Token) { + overview = ( + + ); + } else if (isSmartContract) { + overview = ( + + ); + } else { + overview = ( + + ); + } const tabs = [ { @@ -60,12 +100,12 @@ const AccountDetails = () => { return ( <> - + { coverUrl={state.desmosProfile.coverUrl} /> )} - {isSmartContract - ? ( - - ) - : ( - - )} + {overview} {isSmartContract ? : ( @@ -117,7 +140,7 @@ const AccountDetails = () => { otherTokens={state.otherTokens} /> {!isSmartContract diff --git a/src/screens/account_details/styles.ts b/src/screens/account_details/styles.ts index a4aff803a2..4c98c8ab7e 100644 --- a/src/screens/account_details/styles.ts +++ b/src/screens/account_details/styles.ts @@ -27,22 +27,27 @@ export const useStyles = () => { // gridColumn: '1 / 3', }, }, - cw20tokenBalances: { + overview: { [theme.breakpoints.up('lg')]: { // gridColumn: '1 / 3', }, }, - overview: { + staking: { [theme.breakpoints.up('lg')]: { // gridColumn: '1 / 3', }, }, - staking: { + transactions: { [theme.breakpoints.up('lg')]: { // gridColumn: '1 / 3', }, }, - transactions: { + cw20TokenBalances: { + [theme.breakpoints.up('lg')]: { + // gridColumn: '1 / 3', + }, + }, + cw20TokenInfo: { [theme.breakpoints.up('lg')]: { // gridColumn: '1 / 3', }, diff --git a/src/screens/account_details/types.ts b/src/screens/account_details/types.ts index 743dd99fea..a36233621d 100644 --- a/src/screens/account_details/types.ts +++ b/src/screens/account_details/types.ts @@ -41,22 +41,16 @@ export type Cw20TokenBalance = { logo: string, balance: number } -// todo -// export type Cw20TokenInfo = { -// address: string, -// name: string, -// denom: string, -// logo: string, -// exponent: number, -// circulatingSupply: number, -// maxSupply: number, -// minterAddress: string, -// projectUrl: string, -// holders: { -// address: string, -// balance: number -// }[] -// } + +export type Cw20TokenInfo = { + name: string, + denom: string, + exponent: number, + circulatingSupply: number, + maxSupply?: number, + minterAddress?: string, + projectUrl?: string, +} export type AccountDetailState = { loading: boolean; @@ -72,4 +66,5 @@ export type AccountDetailState = { cosmwasm: CosmwasmType; tab: number; cw20TokenBalances: Cw20TokenBalance[]; + cw20TokenInfo: Cw20TokenInfo; } diff --git a/src/screens/account_details/utils.ts b/src/screens/account_details/utils.ts index 1947eff5ef..f9c43e3719 100644 --- a/src/screens/account_details/utils.ts +++ b/src/screens/account_details/utils.ts @@ -13,7 +13,9 @@ import { import { CosmWasmInstantiateDocument, } from '@graphql/cosmwasm'; -import { Cw20TokenBalancesDocument } from '@src/graphql/cw20_tokens'; +import { + Cw20TokenBalancesDocument, Cw20TokenInfoDocument, +} from '@src/graphql/cw20_tokens'; export const fetchCommission = async (address: string) => { const defaultReturnValue = { @@ -161,6 +163,7 @@ export const fetchCW20TokenBalances = async (address: string) => { }, }], }; + try { const { data } = await axios.post(process.env.NEXT_PUBLIC_GRAPHQL_URL, { variables: { @@ -184,3 +187,40 @@ export const fetchCW20TokenBalances = async (address: string) => { return defaultReturnValue; } }; + +export const fetchCW20TokenInfo = async (address: string) => { + const defaultReturnValue = { + cw20TokenInfo: { + name: '', + denom: '', + logo: '', + exponent: 0, + circulatingSupply: 0, + maxSupply: 0, + minterAddress: '', + projectUrl: '', + }, + }; + + try { + const { data } = await axios.post(process.env.NEXT_PUBLIC_GRAPHQL_URL, { + variables: { + address, + }, + query: Cw20TokenInfoDocument, + }); + const tokenInfo = R.pathOr(defaultReturnValue, ['data', 'cw20token_info_by_pk'], data); + + return { + name: tokenInfo.name, + denom: tokenInfo.symbol, + circulatingSupply: tokenInfo.circulating_supply, + exponent: tokenInfo.decimals, + maxSupply: tokenInfo.max_supply, + minterAddress: tokenInfo.minter, + projectUrl: tokenInfo.project_url, + }; + } catch (error) { + return defaultReturnValue; + } +}; From d6d0f3df0a81ce0d9de41c045d829891e47130d0 Mon Sep 17 00:00:00 2001 From: SpaghettiOverload Date: Wed, 26 Oct 2022 15:37:08 +0300 Subject: [PATCH 4/7] CUDOS-1719 / Update Network Switching --- src/configs/chain_config.mainnet.json | 2 +- src/configs/chain_config.testnet.json | 2 +- src/configs/chain_config_temp.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/configs/chain_config.mainnet.json b/src/configs/chain_config.mainnet.json index 2222b6e767..817bfd2637 100644 --- a/src/configs/chain_config.mainnet.json +++ b/src/configs/chain_config.mainnet.json @@ -1,6 +1,6 @@ { "title": "Cudos Block Explorer", - "network": "cudos-artemis-mainnet", + "network": "cudos-1", "icon": "https://wallet.cudos.org/img/logo-icon.cb505cad.svg?sanitize=true", "logo": { "default": "https://wallet.cudos.org/img/logo-dark.e500e625.svg?sanitize=true" diff --git a/src/configs/chain_config.testnet.json b/src/configs/chain_config.testnet.json index 4d09b94d7c..341cd4753b 100644 --- a/src/configs/chain_config.testnet.json +++ b/src/configs/chain_config.testnet.json @@ -1,6 +1,6 @@ { "title": "Cudos Block Explorer", - "network": "cudos-testnet-public-2", + "network": "cudos-testnet-public-3", "icon": "https://wallet.cudos.org/img/logo-icon.cb505cad.svg?sanitize=true", "logo": { "default": "https://wallet.cudos.org/img/logo-dark.e500e625.svg?sanitize=true" diff --git a/src/configs/chain_config_temp.json b/src/configs/chain_config_temp.json index a48efea98f..7a1d354393 100644 --- a/src/configs/chain_config_temp.json +++ b/src/configs/chain_config_temp.json @@ -5,12 +5,12 @@ "links": [ { "name": "Testnet", - "chain_id": "cudos-testnet-public-2", + "chain_id": "cudos-testnet-public-3", "url": "https://explorer.testnet.cudos.org/" }, { "name": "Mainnet", - "chain_id": "TBA", + "chain_id": "cudos-1", "url": "https://explorer.cudos.org/" } ] From e32fada40a1ea3d0f5cbf76539592bac64a014d9 Mon Sep 17 00:00:00 2001 From: Tugay Emin Date: Mon, 7 Nov 2022 07:27:36 +0200 Subject: [PATCH 5/7] refactor: move cw20 token info to new screen --- i18n.js | 1 + public/locales/en/accounts.json | 10 +-- public/locales/en/token.json | 10 +++ .../nav/components/seach_bar/hooks.tsx | 6 +- src/pages/token/[address].tsx | 9 +++ .../components/desktop/index.tsx | 2 + .../components/mobile/index.tsx | 2 + src/screens/account_details/hooks.ts | 11 ---- src/screens/account_details/index.tsx | 65 ++++++------------- src/screens/account_details/styles.ts | 5 -- src/screens/account_details/types.ts | 11 ---- src/screens/account_details/utils.ts | 39 +---------- .../components/overview}/index.tsx | 2 +- src/screens/token_details/hooks.ts | 38 +++++++++++ src/screens/token_details/index.tsx | 40 ++++++++++++ src/screens/token_details/styles.ts | 40 ++++++++++++ src/screens/token_details/types.ts | 10 +++ src/screens/token_details/utils.ts | 43 ++++++++++++ src/utils/go_to_page.ts | 1 + 19 files changed, 225 insertions(+), 120 deletions(-) create mode 100644 public/locales/en/token.json create mode 100644 src/pages/token/[address].tsx rename src/screens/{account_details/components/cw20_token_overview => token_details/components/overview}/index.tsx (96%) create mode 100644 src/screens/token_details/hooks.ts create mode 100644 src/screens/token_details/index.tsx create mode 100644 src/screens/token_details/styles.ts create mode 100644 src/screens/token_details/types.ts create mode 100644 src/screens/token_details/utils.ts diff --git a/i18n.js b/i18n.js index a31911898a..f41a228a6f 100644 --- a/i18n.js +++ b/i18n.js @@ -12,6 +12,7 @@ module.exports = { 'rgx:^/validators': ['validators', 'transactions', 'accounts', 'message_labels', 'message_contents'], 'rgx:^/accounts': ['accounts', 'transactions', 'validators', 'message_labels', 'message_contents'], 'rgx:^/params': ['params'], + 'rgx:^/token': ['token', 'transactions'], }, loadLocaleFrom: (lang, ns) => import(`./public/locales/${lang}/${ns}.json`).then((m) => m.default), }; diff --git a/public/locales/en/accounts.json b/public/locales/en/accounts.json index a5c2fa5964..171978abc7 100644 --- a/public/locales/en/accounts.json +++ b/public/locales/en/accounts.json @@ -40,13 +40,5 @@ "codeId": "Code Id", "instaBlock": "Instantiated At Block", "collateralTransactions": "Collateral Transactions", - "cw20tokens": "CW20 Tokens", - "cw20TokenDetails": "CW20 Token Details", - "name": "Name", - "denom": "Denom", - "exponent": "Exponent", - "circulatingSupply": "Circulating Supply", - "minter": "Minter", - "maxSupply": "Maximum Supply", - "projectUrl": "Project URL" + "cw20tokens": "CW20 Tokens" } diff --git a/public/locales/en/token.json b/public/locales/en/token.json new file mode 100644 index 0000000000..7ac0257122 --- /dev/null +++ b/public/locales/en/token.json @@ -0,0 +1,10 @@ +{ + "overview": "CW20 Token Details", + "name": "Name", + "denom": "Denom", + "exponent": "Exponent", + "circulatingSupply": "Circulating Supply", + "minter": "Minter", + "maxSupply": "Maximum Supply", + "projectUrl": "Project URL" +} diff --git a/src/components/nav/components/seach_bar/hooks.tsx b/src/components/nav/components/seach_bar/hooks.tsx index 536f038fb9..1168199dc2 100644 --- a/src/components/nav/components/seach_bar/hooks.tsx +++ b/src/components/nav/components/seach_bar/hooks.tsx @@ -7,12 +7,14 @@ import { BLOCK_DETAILS, TRANSACTION_DETAILS, PROFILE_DETAILS, + TOKEN_DETAILS, } from '@utils/go_to_page'; import { useRecoilCallback, } from 'recoil'; import { readValidator } from '@recoil/validators'; import { toast } from 'react-toastify'; +import { fetchCW20TokenInfo } from '@src/screens/token_details/utils'; export const useSearchBar = (t) => { const router = useRouter(); @@ -23,7 +25,7 @@ export const useSearchBar = (t) => { const validatorRegex = `^(${chainConfig.prefix.validator})`; const userRegex = `^(${chainConfig.prefix.account})`; const parsedValue = value.replace(/\s+/g, ''); - + const tokenInfo = await fetchCW20TokenInfo(parsedValue); if (new RegExp(consensusRegex).test(parsedValue)) { const validatorAddress = await snapshot.getPromise(readValidator(parsedValue)); if (validatorAddress) { @@ -33,6 +35,8 @@ export const useSearchBar = (t) => { } } else if (new RegExp(validatorRegex).test(parsedValue)) { router.push(VALIDATOR_DETAILS(parsedValue)); + } else if (tokenInfo.name) { + router.push(TOKEN_DETAILS(parsedValue)); } else if (new RegExp(userRegex).test(parsedValue)) { router.push(ACCOUNT_DETAILS(parsedValue)); } else if (/^@/.test(parsedValue)) { diff --git a/src/pages/token/[address].tsx b/src/pages/token/[address].tsx new file mode 100644 index 0000000000..cef6b54975 --- /dev/null +++ b/src/pages/token/[address].tsx @@ -0,0 +1,9 @@ +import TokenDetails from '@src/screens/token_details'; + +const TokenDetailsPage = () => { + return ( + + ); +}; + +export default TokenDetailsPage; diff --git a/src/screens/account_details/components/cw20_token_balances/components/desktop/index.tsx b/src/screens/account_details/components/cw20_token_balances/components/desktop/index.tsx index 623bfbff2a..56fa2e6131 100644 --- a/src/screens/account_details/components/cw20_token_balances/components/desktop/index.tsx +++ b/src/screens/account_details/components/cw20_token_balances/components/desktop/index.tsx @@ -14,6 +14,7 @@ import { import { formatNumber } from '@utils/format_token'; import { Cw20TokenBalance } from '@src/screens/account_details/types'; import { getMiddleEllipsis } from '@utils/get_middle_ellipsis'; +import { TOKEN_DETAILS } from '@src/utils/go_to_page'; import { columns } from './utils'; const Desktop: React.FC<{ @@ -32,6 +33,7 @@ const Desktop: React.FC<{ name={`${b.name} (${b.denom.toUpperCase()})`} address={b.tokenAddress} imageUrl={b.logo} + href={TOKEN_DETAILS} /> ), balance: `${balance} ${b.denom.toUpperCase()}`, diff --git a/src/screens/account_details/components/cw20_token_balances/components/mobile/index.tsx b/src/screens/account_details/components/cw20_token_balances/components/mobile/index.tsx index 289f6c4160..8350905910 100644 --- a/src/screens/account_details/components/cw20_token_balances/components/mobile/index.tsx +++ b/src/screens/account_details/components/cw20_token_balances/components/mobile/index.tsx @@ -9,6 +9,7 @@ import { AvatarName } from '@components'; import { formatNumber } from '@utils/format_token'; import { Cw20TokenBalance } from '@src/screens/account_details/types'; import { getMiddleEllipsis } from '@src/utils/get_middle_ellipsis'; +import { TOKEN_DETAILS } from '@src/utils/go_to_page'; import { useStyles } from './styles'; const Mobile: React.FC<{ @@ -35,6 +36,7 @@ const Mobile: React.FC<{ name={`${b.name} (${b.denom.toUpperCase()})`} address={b.tokenAddress} imageUrl={b.logo} + href={TOKEN_DETAILS} />
diff --git a/src/screens/account_details/hooks.ts b/src/screens/account_details/hooks.ts index ffb9e72648..40678e556c 100644 --- a/src/screens/account_details/hooks.ts +++ b/src/screens/account_details/hooks.ts @@ -20,7 +20,6 @@ import { fetchUnbondingBalance, fetchCosmWasmInstantiation, fetchCW20TokenBalances, - fetchCW20TokenInfo, } from './utils'; const defaultTokenUnit: TokenUnit = { @@ -66,13 +65,6 @@ const initialState: AccountDetailState = { }, tab: 0, cw20TokenBalances: [], - cw20TokenInfo: { - name: '', - denom: '', - logo: '', - exponent: 0, - circulatingSupply: 0, - }, }; export const useAccountDetails = () => { @@ -139,7 +131,6 @@ export const useAccountDetails = () => { fetchRewards(address), fetchCosmWasmInstantiation(address), fetchCW20TokenBalances(address), - fetchCW20TokenInfo(address), ]; const [ commission, @@ -149,7 +140,6 @@ export const useAccountDetails = () => { rewards, cosmWasmInstantiation, cw20TokenBalances, - cw20TokenInfo, ] = await Promise.allSettled(promises); const formattedRawData: any = {}; @@ -163,7 +153,6 @@ export const useAccountDetails = () => { const rawData: any = {}; rawData.cosmwasm = R.pathOr([], ['value'], cosmWasmInstantiation); - rawData.cw20TokenInfo = R.pathOr([], ['value'], cw20TokenInfo); handleSetState(rawData); }; diff --git a/src/screens/account_details/index.tsx b/src/screens/account_details/index.tsx index 46ffff14b8..fc8b3b3fe6 100644 --- a/src/screens/account_details/index.tsx +++ b/src/screens/account_details/index.tsx @@ -23,7 +23,6 @@ import { } from './components'; import { useAccountDetails } from './hooks'; import Cw20TokenBalances from './components/cw20_token_balances'; -import Cw20TokenOverview from './components/cw20_token_overview'; const AccountDetails = () => { const { t } = useTranslation('accounts'); @@ -34,45 +33,6 @@ const AccountDetails = () => { } = useAccountDetails(); const isSmartContract = state.cosmwasm.result_contract_address === state.overview.address; - const isCw20Token = state.cw20TokenInfo.name && state.cw20TokenInfo.name !== ''; - - let title = ''; - if (isCw20Token) { - title = t('cw20TokenDetails'); - } else if (isSmartContract) { - title = t('smartContractDetails'); - } else { - title = t('accountDetails'); - } - - let overview; - if (isCw20Token) { - overview = ( - - ); - } else if (isSmartContract) { - overview = ( - - ); - } else { - overview = ( - - ); - } const tabs = [ { @@ -100,12 +60,12 @@ const AccountDetails = () => { return ( <> - + { coverUrl={state.desmosProfile.coverUrl} /> )} - {overview} + {isSmartContract + ? ( + + ) + : ( + + )} {isSmartContract ? : ( diff --git a/src/screens/account_details/styles.ts b/src/screens/account_details/styles.ts index 4c98c8ab7e..b15d808ff1 100644 --- a/src/screens/account_details/styles.ts +++ b/src/screens/account_details/styles.ts @@ -47,11 +47,6 @@ export const useStyles = () => { // gridColumn: '1 / 3', }, }, - cw20TokenInfo: { - [theme.breakpoints.up('lg')]: { - // gridColumn: '1 / 3', - }, - }, }); }, )(); diff --git a/src/screens/account_details/types.ts b/src/screens/account_details/types.ts index a36233621d..4f19306c28 100644 --- a/src/screens/account_details/types.ts +++ b/src/screens/account_details/types.ts @@ -42,16 +42,6 @@ export type Cw20TokenBalance = { balance: number } -export type Cw20TokenInfo = { - name: string, - denom: string, - exponent: number, - circulatingSupply: number, - maxSupply?: number, - minterAddress?: string, - projectUrl?: string, -} - export type AccountDetailState = { loading: boolean; exists: boolean; @@ -66,5 +56,4 @@ export type AccountDetailState = { cosmwasm: CosmwasmType; tab: number; cw20TokenBalances: Cw20TokenBalance[]; - cw20TokenInfo: Cw20TokenInfo; } diff --git a/src/screens/account_details/utils.ts b/src/screens/account_details/utils.ts index f9c43e3719..1154b3dd20 100644 --- a/src/screens/account_details/utils.ts +++ b/src/screens/account_details/utils.ts @@ -14,7 +14,7 @@ import { CosmWasmInstantiateDocument, } from '@graphql/cosmwasm'; import { - Cw20TokenBalancesDocument, Cw20TokenInfoDocument, + Cw20TokenBalancesDocument, } from '@src/graphql/cw20_tokens'; export const fetchCommission = async (address: string) => { @@ -187,40 +187,3 @@ export const fetchCW20TokenBalances = async (address: string) => { return defaultReturnValue; } }; - -export const fetchCW20TokenInfo = async (address: string) => { - const defaultReturnValue = { - cw20TokenInfo: { - name: '', - denom: '', - logo: '', - exponent: 0, - circulatingSupply: 0, - maxSupply: 0, - minterAddress: '', - projectUrl: '', - }, - }; - - try { - const { data } = await axios.post(process.env.NEXT_PUBLIC_GRAPHQL_URL, { - variables: { - address, - }, - query: Cw20TokenInfoDocument, - }); - const tokenInfo = R.pathOr(defaultReturnValue, ['data', 'cw20token_info_by_pk'], data); - - return { - name: tokenInfo.name, - denom: tokenInfo.symbol, - circulatingSupply: tokenInfo.circulating_supply, - exponent: tokenInfo.decimals, - maxSupply: tokenInfo.max_supply, - minterAddress: tokenInfo.minter, - projectUrl: tokenInfo.project_url, - }; - } catch (error) { - return defaultReturnValue; - } -}; diff --git a/src/screens/account_details/components/cw20_token_overview/index.tsx b/src/screens/token_details/components/overview/index.tsx similarity index 96% rename from src/screens/account_details/components/cw20_token_overview/index.tsx rename to src/screens/token_details/components/overview/index.tsx index 393f8c0414..d9ae8f4eaf 100644 --- a/src/screens/account_details/components/cw20_token_overview/index.tsx +++ b/src/screens/token_details/components/overview/index.tsx @@ -12,7 +12,7 @@ const Cw20TokenOverview: React.FC<{ return null; } - const { t } = useTranslation('accounts'); + const { t } = useTranslation('token'); const details = [ { diff --git a/src/screens/token_details/hooks.ts b/src/screens/token_details/hooks.ts new file mode 100644 index 0000000000..d6d753ebe7 --- /dev/null +++ b/src/screens/token_details/hooks.ts @@ -0,0 +1,38 @@ +import { + useState, useEffect, +} from 'react'; +import * as R from 'ramda'; +import { useRouter } from 'next/router'; +import { Cw20TokenInfo } from './types'; +import { fetchCW20TokenInfo } from './utils'; + +const initialState: Cw20TokenInfo = { + address: '', + name: '', + denom: '', + exponent: 0, + circulatingSupply: 0, +}; + +export const useTokenDetails = () => { + const router = useRouter(); + const [state, setState] = useState(initialState); + + const handleSetState = (stateChange: any) => { + setState((prevState) => R.mergeDeepLeft(stateChange, prevState)); + }; + + useEffect(() => { + fetchTokenInfo(); + }, [router.query.address]); + + const fetchTokenInfo = async () => { + const address = router.query.address as string; + const tokenInfo = await fetchCW20TokenInfo(address); + handleSetState(tokenInfo); + }; + + return { + state, + }; +}; diff --git a/src/screens/token_details/index.tsx b/src/screens/token_details/index.tsx new file mode 100644 index 0000000000..263289133c --- /dev/null +++ b/src/screens/token_details/index.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import useTranslation from 'next-translate/useTranslation'; +import { + Layout, + ContractMessages, +} from '@components'; +import { NextSeo } from 'next-seo'; +import Cw20TokenOverview from './components/overview'; +import { useStyles } from './styles'; +import { useTokenDetails } from './hooks'; + +const TokenDetails = () => { + const { t } = useTranslation('token'); + const classes = useStyles(); + const { state } = useTokenDetails(); + const title = t('cw20TokenDetails'); + + return ( + <> + + + + + + + + + ); +}; + +export default TokenDetails; diff --git a/src/screens/token_details/styles.ts b/src/screens/token_details/styles.ts new file mode 100644 index 0000000000..44d21c549d --- /dev/null +++ b/src/screens/token_details/styles.ts @@ -0,0 +1,40 @@ +import { makeStyles } from '@material-ui/core/styles'; + +export const useStyles = () => { + const styles = makeStyles( + (theme) => { + return ({ + root: { + ...theme.mixins.layout, + display: 'grid', + gridTemplateRows: 'auto', + gridGap: theme.spacing(1), + '& a': { + color: theme.palette.custom.fonts.highlight, + }, + [theme.breakpoints.up('lg')]: { + gridGap: theme.spacing(2), + // gridTemplateColumns: 'repeat(2, 1fr)', + }, + }, + overview: { + [theme.breakpoints.up('lg')]: { + // gridColumn: '1 / 3', + }, + }, + cw20TokenInfo: { + [theme.breakpoints.up('lg')]: { + // gridColumn: '1 / 3', + }, + }, + transactions: { + [theme.breakpoints.up('lg')]: { + // gridColumn: '1 / 3', + }, + }, + }); + }, + )(); + + return styles; +}; diff --git a/src/screens/token_details/types.ts b/src/screens/token_details/types.ts new file mode 100644 index 0000000000..10009b11ec --- /dev/null +++ b/src/screens/token_details/types.ts @@ -0,0 +1,10 @@ +export type Cw20TokenInfo = { + address: string, + name: string, + denom: string, + exponent: number, + circulatingSupply: number, + maxSupply?: number, + minterAddress?: string, + projectUrl?: string, +} diff --git a/src/screens/token_details/utils.ts b/src/screens/token_details/utils.ts new file mode 100644 index 0000000000..bf72fbdac4 --- /dev/null +++ b/src/screens/token_details/utils.ts @@ -0,0 +1,43 @@ +import { Cw20TokenInfoDocument } from '@src/graphql/cw20_tokens'; +import axios from 'axios'; +import * as R from 'ramda'; +import { Cw20TokenInfo } from './types'; + +export const fetchCW20TokenInfo = async (address: string):Promise => { + const defaultReturnValue = { + cw20TokenInfo: { + address: '', + name: '', + denom: '', + logo: '', + exponent: 0, + circulatingSupply: 0, + maxSupply: 0, + minterAddress: '', + projectUrl: '', + }, + }; + + try { + const { data } = await axios.post(process.env.NEXT_PUBLIC_GRAPHQL_URL, { + variables: { + address, + }, + query: Cw20TokenInfoDocument, + }); + const tokenInfo = R.pathOr(defaultReturnValue, ['data', 'cw20token_info_by_pk'], data); + + return { + address, + name: tokenInfo.name, + denom: tokenInfo.symbol, + circulatingSupply: tokenInfo.circulating_supply, + exponent: tokenInfo.decimals, + maxSupply: tokenInfo.max_supply, + minterAddress: tokenInfo.minter, + projectUrl: tokenInfo.project_url, + }; + } catch (error) { + return defaultReturnValue.cw20TokenInfo; + } +}; diff --git a/src/utils/go_to_page.ts b/src/utils/go_to_page.ts index 52fc56b1ae..568ae8e937 100644 --- a/src/utils/go_to_page.ts +++ b/src/utils/go_to_page.ts @@ -10,6 +10,7 @@ export const TRANSACTION_DETAILS = (tx: string): string => `/transactions/${tx}` export const PROPOSALS = '/proposals'; export const PROPOSAL_DETAILS = (id:string | number): string => `/proposals/${id}`; export const ACCOUNT_DETAILS = (address: string): string => `/accounts/${address}`; +export const TOKEN_DETAILS = (address: string): string => `/token/${address}`; export const PARAMS = '/params'; export const PROFILE_DETAILS = (dtag: string):string => `/${dtag}`; From d1717fdc2a901abf9d0706811b7924e2ba38347f Mon Sep 17 00:00:00 2001 From: infra1515 Date: Mon, 14 Nov 2022 14:55:12 +0200 Subject: [PATCH 6/7] attempt to fix javascript heap out of memory, consistent container name addded to docker compose --- docker-compose-dev.yml | 1 + docker-compose-prod.yml | 1 + next.config.js | 3 +++ 3 files changed, 5 insertions(+) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index b6b43c8054..2660e6d4df 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -1,6 +1,7 @@ version: '3.6' services: big-dipper-2: + container_name: explorer-v2 build: context: . dockerfile: Dockerfile-dev diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index 0df4681305..60ea0885de 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -1,6 +1,7 @@ version: '3.6' services: big-dipper-2: + container_name: explorer-v2 build: context: . dockerfile: Dockerfile-prod diff --git a/next.config.js b/next.config.js index 6857806c1b..f662a451f1 100644 --- a/next.config.js +++ b/next.config.js @@ -9,4 +9,7 @@ module.exports = nextTranslate({ }); return config; }, + experimental: { + esmExternals: false, + }, }); From 200196a6824ca4fe49110675f26358dc55b5ac5b Mon Sep 17 00:00:00 2001 From: infra1515 Date: Mon, 14 Nov 2022 17:40:47 +0200 Subject: [PATCH 7/7] attempt to fix javascript heap out of memory - ENV NODE_OPTIONS="--max-old-space-size=8192" option added --- Dockerfile-dev | 3 +++ Dockerfile-prod | 1 + next.config.js | 3 --- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Dockerfile-dev b/Dockerfile-dev index dce7f8fdb9..5107e20984 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -26,6 +26,7 @@ ARG NEXT_PUBLIC_CHAIN_STATUS ARG NODE_ENV ARG PORT=3000 + # Generate env file ENV NEXT_PUBLIC_GRAPHQL_URL ${NEXT_PUBLIC_GRAPHQL_URL} ENV NEXT_PUBLIC_GRAPHQL_WS ${NEXT_PUBLIC_GRAPHQL_WS} @@ -34,6 +35,8 @@ ENV NEXT_PUBLIC_WS_CHAIN_URL ${NEXT_PUBLIC_WS_CHAIN_URL} ENV NEXT_PUBLIC_CHAIN_STATUS ${NEXT_PUBLIC_CHAIN_STATUS} ENV NODE_ENV ${NODE_ENV} ENV PORT ${PORT} +ENV NODE_OPTIONS="--max-old-space-size=8192" + # # Update schema diff --git a/Dockerfile-prod b/Dockerfile-prod index 71479ec7e9..80399e77d2 100644 --- a/Dockerfile-prod +++ b/Dockerfile-prod @@ -40,6 +40,7 @@ ENV NEXT_PUBLIC_CHAIN_STATUS ${NEXT_PUBLIC_CHAIN_STATUS} ENV NEXT_PUBLIC_CHAIN_TYPE ${NEXT_PUBLIC_CHAIN_TYPE} ENV NODE_ENV ${NODE_ENV} ENV PORT ${PORT} +ENV NODE_OPTIONS="--max-old-space-size=8192" # Update schema # RUN npm run graphql:codegen diff --git a/next.config.js b/next.config.js index f662a451f1..6857806c1b 100644 --- a/next.config.js +++ b/next.config.js @@ -9,7 +9,4 @@ module.exports = nextTranslate({ }); return config; }, - experimental: { - esmExternals: false, - }, });