diff --git a/package-lock.json b/package-lock.json index f5bfe79e0..a5f598fc1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,11 +12,11 @@ "@mui/icons-material": "^5.8.0", "@mui/material": "^5.9.1", "@sentry/react": "^7.53.1", - "@terra-money/feather.js": "^1.0.4", + "@terra-money/feather.js": "^1.0.6", "@terra-money/ledger-station-js": "^1.3.7", "@terra-money/log-finder-ruleset": "^3.0.0", "@terra-money/terra-utils": "^1.0.9", - "@terra-money/terra.js": "^3.1.7", + "@terra-money/terra.js": "^3.1.9", "@terra-money/terra.proto": "^2.0.0", "@terra-money/use-wallet": "4.0.0-beta.3", "@terra-money/wallet-controller": "4.0.0-beta.3", @@ -2011,6 +2011,17 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@classic-terra/terra.proto": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@classic-terra/terra.proto/-/terra.proto-1.1.0.tgz", + "integrity": "sha512-bYhQG5LUaGF0KPRY9hYT/HEcd1QExZPQd6zLV/rQkCe/eDxfwFRLzZHpaaAdfWoAAZjsRWqJbUCqCg7gXBbJpw==", + "dependencies": { + "@improbable-eng/grpc-web": "^0.14.1", + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, "node_modules/@cnakazawa/watch": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", @@ -4082,9 +4093,9 @@ } }, "node_modules/@terra-money/feather.js": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-1.0.4.tgz", - "integrity": "sha512-EevGNBJjz7igdYxX7joexXcU5/eYlyNxGnS88UnwK+vBJ+hTnIOKBIwcNOxttFsyNMZok3XefArloM34ccTvng==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-1.0.6.tgz", + "integrity": "sha512-X1jldkXOAgtuFJZNQM7YXfMgGt/Cdy4qMB86v1YprjjqxAe468gVyzYDfrMk9O3QK3DkyZw0iO4m3+a1vmcZlw==", "dependencies": { "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", "@terra-money/terra.proto": "3.0.5", @@ -4190,11 +4201,11 @@ "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==" }, "node_modules/@terra-money/terra.js": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.7.tgz", - "integrity": "sha512-z7NwVI1gh0846pgQJaPHya6SRKLd/dHWR5UwWG6T2Pf24I2EjCo8YY5Fay30pCvHTYA2NBFgnWfXEZ/31TfB1Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.9.tgz", + "integrity": "sha512-JulSvOHLM56fL7s+cIjIbZeWPBluq883X1soWxA4TG5rKkDythT/DHeLXr3jP5Ld/26VENPSg6lNvK7cEYKpiw==", "dependencies": { - "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", + "@classic-terra/terra.proto": "^1.1.0", "@terra-money/terra.proto": "^2.1.0", "axios": "^0.27.2", "bech32": "^2.0.0", @@ -28869,6 +28880,17 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@classic-terra/terra.proto": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@classic-terra/terra.proto/-/terra.proto-1.1.0.tgz", + "integrity": "sha512-bYhQG5LUaGF0KPRY9hYT/HEcd1QExZPQd6zLV/rQkCe/eDxfwFRLzZHpaaAdfWoAAZjsRWqJbUCqCg7gXBbJpw==", + "requires": { + "@improbable-eng/grpc-web": "^0.14.1", + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, "@cnakazawa/watch": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", @@ -30418,9 +30440,9 @@ } }, "@terra-money/feather.js": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-1.0.4.tgz", - "integrity": "sha512-EevGNBJjz7igdYxX7joexXcU5/eYlyNxGnS88UnwK+vBJ+hTnIOKBIwcNOxttFsyNMZok3XefArloM34ccTvng==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-1.0.6.tgz", + "integrity": "sha512-X1jldkXOAgtuFJZNQM7YXfMgGt/Cdy4qMB86v1YprjjqxAe468gVyzYDfrMk9O3QK3DkyZw0iO4m3+a1vmcZlw==", "requires": { "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", "@terra-money/terra.proto": "3.0.5", @@ -30517,11 +30539,11 @@ } }, "@terra-money/terra.js": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.7.tgz", - "integrity": "sha512-z7NwVI1gh0846pgQJaPHya6SRKLd/dHWR5UwWG6T2Pf24I2EjCo8YY5Fay30pCvHTYA2NBFgnWfXEZ/31TfB1Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.9.tgz", + "integrity": "sha512-JulSvOHLM56fL7s+cIjIbZeWPBluq883X1soWxA4TG5rKkDythT/DHeLXr3jP5Ld/26VENPSg6lNvK7cEYKpiw==", "requires": { - "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", + "@classic-terra/terra.proto": "^1.1.0", "@terra-money/terra.proto": "^2.1.0", "axios": "^0.27.2", "bech32": "^2.0.0", diff --git a/package.json b/package.json index 15671f899..2aed7ca72 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,11 @@ "@mui/icons-material": "^5.8.0", "@mui/material": "^5.9.1", "@sentry/react": "^7.53.1", - "@terra-money/feather.js": "^1.0.4", + "@terra-money/feather.js": "^1.0.6", "@terra-money/ledger-station-js": "^1.3.7", "@terra-money/log-finder-ruleset": "^3.0.0", "@terra-money/terra-utils": "^1.0.9", - "@terra-money/terra.js": "^3.1.7", + "@terra-money/terra.js": "^3.1.9", "@terra-money/terra.proto": "^2.0.0", "@terra-money/use-wallet": "4.0.0-beta.3", "@terra-money/wallet-controller": "4.0.0-beta.3", diff --git a/src/app/InitBankBalance.tsx b/src/app/InitBankBalance.tsx index 55a3bf1f5..a398f09c4 100644 --- a/src/app/InitBankBalance.tsx +++ b/src/app/InitBankBalance.tsx @@ -30,7 +30,8 @@ const InitBankBalance = ({ children }: PropsWithChildren<{}>) => { ) native.list.forEach(({ id }) => { - const [chain, denom] = id.split(":") + const [chain, ...denomData] = id.split(":") + const denom = denomData.join(":") if ( !bankBalance.find( (balance) => balance.denom === denom && balance.chain === chain diff --git a/src/components/display/DateTimeRenderer.tsx b/src/components/display/DateTimeRenderer.tsx new file mode 100644 index 000000000..4eda567ed --- /dev/null +++ b/src/components/display/DateTimeRenderer.tsx @@ -0,0 +1,25 @@ +import { ToNow } from "." + +const validFormats = ["relative", "localestring"] as const + +interface Props { + children: string | Date + format: typeof validFormats[number] + update?: boolean +} + +const DateTimeRenderer = ({ children: timestamp, format, update }: Props) => { + const dateString = + typeof timestamp === "string" ? timestamp : timestamp.toISOString() + + switch (format) { + case "relative": + return {new Date(dateString)} + case "localestring": + return {new Date(dateString).toLocaleString()} + default: + return {dateString} + } +} + +export default DateTimeRenderer diff --git a/src/components/display/index.ts b/src/components/display/index.ts index c2fbaf09d..95cd1fb84 100644 --- a/src/components/display/index.ts +++ b/src/components/display/index.ts @@ -5,4 +5,5 @@ export * from "./List" export { default as Tag } from "./Tag" export { default as ToNow } from "./ToNow" export { default as Tooltip } from "./Tooltip" +export { default as DateTimeRenderer } from "./DateTimeRenderer" export * from "./Tooltip" diff --git a/src/components/general/CopyIcon.tsx b/src/components/general/CopyIcon.tsx index 113491572..8eda28370 100644 --- a/src/components/general/CopyIcon.tsx +++ b/src/components/general/CopyIcon.tsx @@ -5,8 +5,9 @@ import { useState } from "react" interface Props { text: string className?: string + size?: number } -const CopyIcon = ({ text, className }: Props) => { +const CopyIcon = ({ text, className, size }: Props) => { const [copied, setCopied] = useState(false) return ( @@ -19,9 +20,9 @@ const CopyIcon = ({ text, className }: Props) => { }} > {copied ? ( - + ) : ( - + )} ) diff --git a/src/components/token/TokenIcon.module.scss b/src/components/token/TokenIcon.module.scss index 3047e6f0f..9c0ec4eb1 100644 --- a/src/components/token/TokenIcon.module.scss +++ b/src/components/token/TokenIcon.module.scss @@ -1,6 +1,5 @@ .icon { border-radius: 50%; - background-color: var(--button-default-bg); } .inherit { diff --git a/src/components/token/TokenIcon.tsx b/src/components/token/TokenIcon.tsx index c05f74d9c..28a6b3a40 100644 --- a/src/components/token/TokenIcon.tsx +++ b/src/components/token/TokenIcon.tsx @@ -27,9 +27,8 @@ const TokenIcon = ({ token, icon, size, ...rest }: Props) => { size === "inherit" ? undefined : { - width: size ?? 34, - height: size ?? 34, - style: { padding: (size ?? 34) / 3.5 }, + width: size ?? 24, + height: size ?? 24, } const attrs = { ...rest, ...sizes, src, className: cx(styles.icon, size) } diff --git a/src/data/token.tsx b/src/data/token.tsx index 77b60a4dc..8238310a7 100644 --- a/src/data/token.tsx +++ b/src/data/token.tsx @@ -90,7 +90,10 @@ export const useNativeDenoms = () => { let decimals = DEFAULT_NATIVE_DECIMALS - function readNativeDenom(denom: Denom, chainID?: string): TokenItem { + function readNativeDenom( + denom: Denom, + chainID?: string + ): TokenItem & { isNonWhitelisted?: boolean } { let tokenType = "" if (denom.startsWith("ibc/")) { @@ -114,8 +117,12 @@ export const useNativeDenoms = () => { break case "factory": { - // TODO - lookup whitelist for factory tokens. - fixedDenom = "..." + const factoryParts = denom.split(/[/:]/) + let tokenAddress = "" + if (factoryParts.length >= 2) { + tokenAddress = factoryParts.slice(2).join(" ") + } + fixedDenom = tokenAddress break } @@ -176,6 +183,7 @@ export const useNativeDenoms = () => { ? factoryIcon : "https://assets.terra.money/icon/svg/Terra.svg", decimals, + isNonWhitelisted: true, } ) } diff --git a/src/pages/gov/ProposalDeposits.tsx b/src/pages/gov/ProposalDeposits.tsx index 0e81e0693..4d77e0f45 100644 --- a/src/pages/gov/ProposalDeposits.tsx +++ b/src/pages/gov/ProposalDeposits.tsx @@ -7,7 +7,7 @@ import { useProposal } from "data/queries/gov" import { useDeposits, useDepositParams } from "data/queries/gov" import { Card } from "components/layout" import { Read } from "components/token" -import { ToNow } from "components/display" +import { DateTimeRenderer } from "components/display" import Orb from "./components/Orb" import styles from "./ProposalDeposits.module.scss" import { useNetwork } from "data/wallet" @@ -55,7 +55,11 @@ const ProposalDeposits = ({ id, chain, card }: Props) => { }, { title: t("Deposit end time"), - content: {new Date(deposit_end_time)}, + content: ( + + {deposit_end_time} + + ), }, ] diff --git a/src/pages/gov/ProposalHeader.tsx b/src/pages/gov/ProposalHeader.tsx index c7fe3ea20..6f2b0b3f9 100644 --- a/src/pages/gov/ProposalHeader.tsx +++ b/src/pages/gov/ProposalHeader.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next" import { ProposalResult, useParseProposalType } from "data/queries/gov" import { useProposalStatusItem } from "data/queries/gov" -import { ToNow } from "components/display" +import { DateTimeRenderer } from "components/display" import styles from "./ProposalHeader.module.scss" import { useNetwork } from "data/wallet" @@ -34,7 +34,10 @@ const ProposalHeader = ({

{title}

- {t("Submitted")} {new Date(submit_time)} + {t("Submitted")}{" "} + + {submit_time} +

) diff --git a/src/pages/gov/ProposalVotes.tsx b/src/pages/gov/ProposalVotes.tsx index 8aab47b86..831b95ef0 100644 --- a/src/pages/gov/ProposalVotes.tsx +++ b/src/pages/gov/ProposalVotes.tsx @@ -11,7 +11,7 @@ import { useStakingPool } from "data/queries/staking" import { Col, Row, Card, Grid } from "components/layout" import { Fetching, Empty } from "components/feedback" import { Read } from "components/token" -import { ToNow } from "components/display" +import { DateTimeRenderer } from "components/display" import VoteProgress from "./components/VoteProgress" import styles from "./ProposalVotes.module.scss" @@ -121,7 +121,9 @@ const ProposalVotes = ({

{new Date(voting_end_time) > new Date() ? t("Ends") : t("Ended")}{" "} - {new Date(voting_end_time)} + + {voting_end_time} +

diff --git a/src/pages/gov/components/VoteProgress.module.scss b/src/pages/gov/components/VoteProgress.module.scss index 5f938713a..a5842311d 100644 --- a/src/pages/gov/components/VoteProgress.module.scss +++ b/src/pages/gov/components/VoteProgress.module.scss @@ -5,7 +5,7 @@ .label, .line { - transform: translate(-50%, 0); + transform: translate(var(--x-pos), 0); } } diff --git a/src/pages/gov/components/VoteProgress.tsx b/src/pages/gov/components/VoteProgress.tsx index 9c09f2172..f5bd9fec0 100644 --- a/src/pages/gov/components/VoteProgress.tsx +++ b/src/pages/gov/components/VoteProgress.tsx @@ -1,12 +1,40 @@ -import { PropsWithChildren } from "react" -import classNames from "classnames" -import { Flex } from "components/layout" +import { useLayoutEffect, PropsWithChildren, useRef, useState } from "react" import styles from "./VoteProgress.module.scss" +import { Flex } from "components/layout" +import classNames from "classnames" const Flag = ({ left, children }: PropsWithChildren<{ left: string }>) => { + const ref = useRef(null) + const [width, setWidth] = useState(0) + + useLayoutEffect(() => { + if (ref.current) setWidth(ref.current.offsetWidth) + }, [ref.current?.offsetWidth]) + + let maxTranslate = 45 + switch (children) { + case "Pass Threshold": + maxTranslate = 45 + break + case "Vote Threshold": + maxTranslate = 45.3 + break + case "Quorum": + maxTranslate = 23.9 + break + } + + const translateStyle = { + "--x-pos": + (parseFloat(left) / 100) * width < maxTranslate + ? `-${(parseFloat(left) / 100) * width}px` + : "-50%", + } as React.CSSProperties return ( -
- {children} +
+ + {children} +
) diff --git a/src/pages/history/HistoryItem.tsx b/src/pages/history/HistoryItem.tsx index f65b61be8..5282265cd 100644 --- a/src/pages/history/HistoryItem.tsx +++ b/src/pages/history/HistoryItem.tsx @@ -2,7 +2,7 @@ import { Fragment } from "react" import { useTranslation } from "react-i18next" import { FinderLink } from "components/general" import { Card } from "components/layout" -import { Dl, ToNow } from "components/display" +import { Dl, DateTimeRenderer } from "components/display" import { ReadMultiple } from "components/token" import HistoryMessage from "./HistoryMessage" import styles from "./HistoryItem.module.scss" @@ -73,7 +73,9 @@ const HistoryItem = ({

- {new Date(timestamp)} + + {timestamp} +

diff --git a/src/pages/stake/ValidatorCommission.tsx b/src/pages/stake/ValidatorCommission.tsx index 26b76ab96..920280e33 100644 --- a/src/pages/stake/ValidatorCommission.tsx +++ b/src/pages/stake/ValidatorCommission.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next" import { readPercent } from "@terra-money/terra-utils" import { Card } from "components/layout" -import { ToNow } from "components/display" +import { DateTimeRenderer } from "components/display" import ValidatorNumbers from "./components/ValidatorNumbers" import { Validator } from "@terra-money/feather.js" @@ -27,7 +27,11 @@ const ValidatorCommission = ({ validator }: { validator: Validator }) => { }, { title: t("Last changed"), - content: {new Date(update_time)}, + content: ( + + {update_time} + + ), }, ] diff --git a/src/pages/stake/ValidatorCompact.tsx b/src/pages/stake/ValidatorCompact.tsx index 494b46d9a..957fe3ae9 100644 --- a/src/pages/stake/ValidatorCompact.tsx +++ b/src/pages/stake/ValidatorCompact.tsx @@ -9,7 +9,7 @@ import styles from "./ValidatorCompact.module.scss" import ProfileIcon from "./components/ProfileIcon" import { useTranslation } from "react-i18next" import { readPercent } from "@terra-money/terra-utils" -import { ToNow } from "components/display" +import { DateTimeRenderer } from "components/display" const cx = classNames.bind(styles) @@ -66,7 +66,9 @@ const ValidatorCompact = ({ vertical }: { vertical?: boolean }) => {
{t("Last changed")}
- {new Date(update_time)} + + {update_time} +
diff --git a/src/pages/stake/unbondings/ChainUnbondings.tsx b/src/pages/stake/unbondings/ChainUnbondings.tsx index 02a7aa258..aa8c5cdf0 100644 --- a/src/pages/stake/unbondings/ChainUnbondings.tsx +++ b/src/pages/stake/unbondings/ChainUnbondings.tsx @@ -12,7 +12,7 @@ import { ValidatorLink } from "components/general" import { ModalButton } from "components/feedback" import { Table } from "components/layout" import { Read } from "components/token" -import { ToNow, TooltipIcon } from "components/display" +import { DateTimeRenderer, TooltipIcon } from "components/display" import StakedCard from "../components/StakedCard" import styles from "../CardModal.module.scss" @@ -119,7 +119,11 @@ const ChainUnbondings = ({ chain }: { chain: string }) => { { title: t("Release"), dataIndex: "completion_time", - render: (date: Date) => {date}, + render: (date: Date) => ( + + {date} + + ), align: "right", }, ]} diff --git a/src/pages/stake/unbondings/Unbondings.tsx b/src/pages/stake/unbondings/Unbondings.tsx index 3c39f0c90..848fd51e1 100644 --- a/src/pages/stake/unbondings/Unbondings.tsx +++ b/src/pages/stake/unbondings/Unbondings.tsx @@ -11,7 +11,7 @@ import { ValidatorLink } from "components/general" import { ModalButton } from "components/feedback" import { Table } from "components/layout" import { Read } from "components/token" -import { ToNow, TooltipIcon } from "components/display" +import { DateTimeRenderer, TooltipIcon } from "components/display" import StakedCard from "../components/StakedCard" import { UnbondingDelegation } from "@terra-money/feather.js" import { useNetwork } from "data/wallet" @@ -103,7 +103,11 @@ const Unbondings = () => { { title: t("Release"), dataIndex: "completion_time", - render: (date: Date) => {date}, + render: (date: Date) => ( + + {date} + + ), align: "right", }, ]} diff --git a/src/pages/wallet/Asset.module.scss b/src/pages/wallet/Asset.module.scss index a2053ae7d..7de1c0122 100644 --- a/src/pages/wallet/Asset.module.scss +++ b/src/pages/wallet/Asset.module.scss @@ -10,55 +10,70 @@ &:hover { background-color: var(--card-bg); - - .details__container { - grid-template-areas: - "symbol symbol" - "change amount"; - } - - .chain__num, - .price { - display: none; - } - - .chains { - display: inline; - background-color: var(--button-default-bg); - padding: 2px 10px; - font-size: 12px; - border-radius: 10px; - } } } .details { @include flex(flex-start); - gap: 10px; + gap: 16px; width: 100%; + + .token__icon__container { + position: relative; + + .chain__icon { + position: absolute; + bottom: -8px; + right: -10px; + width: 20px; + height: 20px; + padding: 2px; + border-radius: 50%; + background-color: var(--card-bg-muted); + } + } } .details__container { - display: grid; width: 100%; - max-width: 100%; - grid-template-areas: - "symbol price" - "change amount"; + max-width: calc(100% - 40px); + display: flex; + flex-direction: column; + + .top__row { + display: flex; + justify-content: space-between; + align-items: center; + gap: 24px; + } + + .bottom__row { + display: flex; + justify-content: space-between; + align-items: center; + } } .symbol { @include flex(flex-start); gap: 6px; - font-size: 15px; - grid-area: symbol; + font-size: 16px; + overflow: hidden; + + .symbol__name { + white-space: nowrap; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + } } .chain__num { - background-color: var(--button-default-bg); - padding: 2px 10px; + background-color: var(--bg-muted); + padding: 2px 8px; font-size: 12px; - border-radius: 10px; + line-height: 130%; + border-radius: 4px; } .chains { @@ -66,19 +81,28 @@ } .amount { - font-size: 15px; - grid-area: amount; + font-size: 12px; font-weight: var(--normal); color: var(--text-muted); text-align: right; white-space: nowrap; + max-width: 100%; + display: flex; + justify-content: flex-end; + gap: 4px; + flex-wrap: wrap; + + .sub__amount { + overflow: hidden; + text-overflow: ellipsis; + max-width: 100px; + } } .change__up, .change__down { @include flex(flex-start); font-weight: var(--normal); - grid-area: change; gap: 4px; } @@ -91,8 +115,12 @@ } .price { - text-align: right; - grid-area: price; + font-size: 16px; + font-weight: var(--bold); + display: flex; + flex-wrap: nowrap; + flex-direction: row; + justify-content: flex-end; } .value { diff --git a/src/pages/wallet/Asset.tsx b/src/pages/wallet/Asset.tsx index cb9a7f301..9ab37d4b6 100644 --- a/src/pages/wallet/Asset.tsx +++ b/src/pages/wallet/Asset.tsx @@ -27,6 +27,7 @@ const Asset = (props: Props) => { const currency = useCurrency() const network = useNetwork() const chains = props.chains.filter((chain) => !!network[chain]) + const singleNetworkIcon = network[chains[0]]?.icon const { data: prices, ...pricesState } = useExchangeRates() const { route, setRoute } = useWalletRoute() @@ -44,61 +45,70 @@ const Asset = (props: Props) => { } >
- - +
+ + {chains && chains.length === 1 && ( + {network[chains[0]]?.name} + )} +
-

- {symbol.length > 16 ? symbol.slice(0, 13) + "..." : symbol} - {chains.map((chain) => ( - - {network[chain].name || chain} - - ))} - {chains && chains.length > 1 && ( - {chains.length} - )} -

-

= 0 ? styles.change__up : styles.change__down}> - {change >= 0 ? : } {change.toFixed(2)}% -

-

- {currency.symbol}{" "} - {coinPrice ? ( - - ) : ( - "—" - )} -

-

- - {(progress, wrong) => ( - <> - {progress} - {wrong ? ( - - {t("Failed to query balance")} - - ) : ( - - )} - +
+

+ {symbol} + {chains && chains.length > 1 && ( + {chains.length} + )} +

+

+ {currency.symbol}{" "} + {coinPrice ? ( + + ) : ( + )} - {" "} - {symbol} -

+

+
+
+

= 0 ? styles.change__up : styles.change__down} + > + {change >= 0 ? : } {change.toFixed(2)}% +

+

+ + {(progress, wrong) => ( + <> + {progress} + {wrong ? ( + + {t("Failed to query balance")} + + ) : ( + + )} + + )} + {" "} + {symbol} +

+
diff --git a/src/pages/wallet/AssetChain.module.scss b/src/pages/wallet/AssetChain.module.scss index a80f85c82..7929e9f39 100644 --- a/src/pages/wallet/AssetChain.module.scss +++ b/src/pages/wallet/AssetChain.module.scss @@ -8,10 +8,6 @@ position: relative; // to loading indicator transition: 300ms; height: fit-content; - - &:hover { - background-color: var(--card-bg); - } } .details { @@ -34,11 +30,24 @@ font-weight: var(--normal); color: var(--text-muted); white-space: nowrap; + + .copy__denom { + display: inline-flex; + align-items: center; + justify-content: flex-start; + gap: 5px; + color: hsl( + var(--button-primary-bg-h), + var(--button-primary-bg-s), + var(--button-primary-bg-l) + ); + } } h4 { @include flex(flex-start); gap: 8px; + font-size: 16px; .send__back__button { color: var(--warning); @@ -59,13 +68,14 @@ .price { grid-area: price; + font-size: 16px; text-align: end; } .amount { grid-area: amount; text-align: end; - font-size: 15px; + font-size: 12px; font-weight: var(--normal); color: var(--text-muted); white-space: nowrap; diff --git a/src/pages/wallet/AssetChain.tsx b/src/pages/wallet/AssetChain.tsx index 7750188c6..4fc817367 100644 --- a/src/pages/wallet/AssetChain.tsx +++ b/src/pages/wallet/AssetChain.tsx @@ -6,8 +6,10 @@ import { useNetwork } from "data/wallet" import { useTranslation } from "react-i18next" import styles from "./AssetChain.module.scss" import IbcSendBack from "./IbcSendBack" -import { InternalButton } from "components/general" +import { CopyIcon, InternalButton } from "components/general" import { Tooltip } from "components/display" +import { useDevMode } from "utils/localStorage" +import { truncate } from "@terra-money/terra-utils" export interface Props { chain: string @@ -15,26 +17,29 @@ export interface Props { symbol: string decimals: number token: string + denom: string path?: string[] ibcDenom?: string } const AssetChain = (props: Props) => { - const { chain, symbol, balance, decimals, token, path, ibcDenom } = props + const { chain, symbol, balance, decimals, token, path, ibcDenom, denom } = + props const currency = useCurrency() const { data: prices, ...pricesState } = useExchangeRates() const { t } = useTranslation() const networks = useNetwork() + const { devMode } = useDevMode() - const { icon, name } = networks[chain] + const { icon, name } = networks[chain] || {} // send back is not available if one of the chains the asset went through is not supprted by Station const isSendBackDisabled = !!path?.find((chain) => !networks[chain]) return (
- +

@@ -78,6 +83,14 @@ const AssetChain = (props: Props) => { ))}

{path &&

{path.map((c) => networks[c]?.name ?? c).join(" → ")}

} + {devMode && ( +

+ + {truncate(denom)} + + +

+ )}

{currency.symbol}{" "} diff --git a/src/pages/wallet/AssetList.module.scss b/src/pages/wallet/AssetList.module.scss index 7ef17312d..bf8148f48 100644 --- a/src/pages/wallet/AssetList.module.scss +++ b/src/pages/wallet/AssetList.module.scss @@ -16,6 +16,21 @@ grid-area: title; } +.manage__button { + display: flex; + gap: 8px; + + svg { + width: 16px; + height: 16px; + + path { + fill: var(--button-primary-bg); + stroke: var(--button-primary-bg); + } + } +} + .assetlist__list { overflow-y: auto; grid-area: list; diff --git a/src/pages/wallet/AssetList.tsx b/src/pages/wallet/AssetList.tsx index 359cee6fc..d6a4e5326 100644 --- a/src/pages/wallet/AssetList.tsx +++ b/src/pages/wallet/AssetList.tsx @@ -16,6 +16,7 @@ import { } from "data/settings/CustomTokens" import { useIBCBaseDenoms } from "data/queries/ibc" import { useNetwork } from "data/wallet" +import { ReactComponent as ManageAssets } from "styles/images/icons/ManageAssets.svg" const AssetList = () => { const { t } = useTranslation() @@ -77,7 +78,7 @@ const AssetList = () => { // @ts-expect-error unknownIBCDenoms[denom]?.chainID ?? data.chainID ?? chain, data.token, - ].join(":") + ].join("*") if (acc[key]) { acc[key].balance = `${ @@ -98,7 +99,7 @@ const AssetList = () => { chains: [chain], id: key, whitelisted: !( - data.symbol.endsWith("...") || + data.isNonWhitelisted || unknownIBCDenoms[denom]?.chainIDs.find((c) => !networks[c]) ), }, @@ -166,7 +167,10 @@ const AssetList = () => {

Assets

{(open) => ( - {t("Manage tokens")} + + {t("Manage")} + + )} diff --git a/src/pages/wallet/AssetPage.module.scss b/src/pages/wallet/AssetPage.module.scss index 947f2a462..ae3597b2f 100644 --- a/src/pages/wallet/AssetPage.module.scss +++ b/src/pages/wallet/AssetPage.module.scss @@ -22,27 +22,31 @@ } } +.chainlist__container { + padding-top: 25px; + padding-bottom: 1.6rem; +} + .chainlist { background-color: var(--card-bg-muted); - padding-top: 1.6rem; padding-inline: 10px; grid-area: list; display: grid; grid-template-areas: "title" "list"; grid-template-rows: min-content auto; overflow-y: hidden; +} - h3 { - padding-left: 10px; - grid-area: title; - margin-bottom: 10px; - } +.chainlist__title { + grid-area: title; + margin-bottom: 5px; + padding-left: 10px; } .chainlist__list { overflow-y: auto; grid-area: list; - padding-bottom: 1.6rem; + padding-bottom: 1rem; } .actions { diff --git a/src/pages/wallet/AssetPage.tsx b/src/pages/wallet/AssetPage.tsx index cbca3c45a..38635d8a1 100644 --- a/src/pages/wallet/AssetPage.tsx +++ b/src/pages/wallet/AssetPage.tsx @@ -21,8 +21,8 @@ const AssetPage = () => { const { t } = useTranslation() const { setRoute, route } = useWalletRoute() const routeDenom = route.path === Path.coin ? route.denom ?? "uluna" : "uluna" - const [chain, denom] = routeDenom.includes(":") - ? routeDenom.split(":") + const [chain, denom] = routeDenom.includes("*") + ? routeDenom.split("*") : [undefined, routeDenom] const { token, symbol, icon, decimals } = readNativeDenom(denom, chain) @@ -70,22 +70,18 @@ const AssetPage = () => {

{currency.symbol}{" "} - +

- - {symbol} + {symbol}

-
+
{filteredBalances.length > 0 && ( -
-

{t("Chains")}

+
+
+

{t("Chains")}

+
{filteredBalances .sort((a, b) => parseInt(b.amount) - parseInt(a.amount)) @@ -96,6 +92,7 @@ const AssetPage = () => { balance={b.amount} chain={b.chain} token={token} + denom={b.denom} decimals={decimals} /> {token === "uluna" && isTerraChain(b.chain) && } @@ -105,8 +102,10 @@ const AssetPage = () => {
)} {filteredUnsupportedBalances.length > 0 && ( -
-

{t("Unsupported Chains")}

+
+
+

{t("Unsupported Chains")}

+
{filteredUnsupportedBalances .sort((a, b) => parseInt(b.amount) - parseInt(a.amount)) @@ -117,6 +116,7 @@ const AssetPage = () => { balance={b.amount} chain={b.chain} token={token} + denom={b.denom} decimals={decimals} path={unknownIBCDenoms[b.denom]?.chains} ibcDenom={b.denom} diff --git a/src/pages/wallet/IbcSendBackTx.tsx b/src/pages/wallet/IbcSendBackTx.tsx index 0e345777b..d63583d50 100644 --- a/src/pages/wallet/IbcSendBackTx.tsx +++ b/src/pages/wallet/IbcSendBackTx.tsx @@ -182,7 +182,7 @@ function IbcSendBackTx({ token, chainID }: Props) { const createTx = useCallback( ({ input }: TxValues) => { - if (!ibcDetails || !addresses || !IBCdenom || input === undefined) return + if (!ibcDetails || !addresses || !IBCdenom || !input) return const msgs = [ new MsgTransfer( @@ -192,7 +192,8 @@ function IbcSendBackTx({ token, chainID }: Props) { addresses[chains[step]], addresses[chains[step + 1]], undefined, - (Date.now() + 120 * 1000) * 1e6 + (Date.now() + 120 * 1000) * 1e6, + undefined ), ] diff --git a/src/pages/wallet/NetWorth.module.scss b/src/pages/wallet/NetWorth.module.scss index eac9d10e9..a25c44236 100644 --- a/src/pages/wallet/NetWorth.module.scss +++ b/src/pages/wallet/NetWorth.module.scss @@ -12,9 +12,10 @@ } h1 { - font-size: 32px; - line-height: 150%; + font-size: 40px; margin-top: 4px; + word-spacing: -10px; + line-height: 120%; } grid-area: details; @@ -23,9 +24,9 @@ } .networth__buttons { display: flex; - gap: 48px; + gap: 40px; justify-content: center; - margin-top: 28px; + margin-top: 24px; width: 100%; .button__wrapper { @@ -41,15 +42,49 @@ padding: 16px; @include flex; } -} -.icon { - font-size: 24px; + .wallet_primary { + box-shadow: inset 0px 1.5px 0px 0px rgb(255 255 255 / 30%), + 0px 4px 24px 0px rgb(36 36 40 / 30%); + transition: all 0.1s ease-in-out; + + &:hover { + box-shadow: inset 0px 1.5px 0px 0px rgb(255 255 255 / 20%), + 0px 4px 24px 0px rgb(36 36 40 / 30%); + } - &.send { - transform: rotate(-90deg); + &:active { + box-shadow: inset 0px 0.25px 0px 0px rgb(255 255 255 / 20%), + 0px 4px 24px 0px rgb(36 36 40 / 30%); + } } - &.receive { - transform: rotate(90deg); + + .wallet_default { + box-shadow: inset 0px 1.5px 0px 0px rgb(255 255 255 / 8%), + 0px 4px 24px 0px rgb(36 36 40 / 30%); + transition: all 0.1s ease-in-out; + + &:hover { + box-shadow: inset 0px 1.5px 0px 0px rgb(255 255 255 / 5%), + 0px 4px 24px 0px rgb(36 36 40 / 30%); + } + + &:active { + box-shadow: inset 0px 0.25px 0px 0px rgb(255 255 255 / 5%), + 0px 4px 24px 0px rgb(36 36 40 / 30%); + } + + svg { + width: 18px; + height: 18px; + + path { + fill: var(--button-default-text); + } + } } } + +.icon { + font-size: 24px; +} diff --git a/src/pages/wallet/NetWorth.tsx b/src/pages/wallet/NetWorth.tsx index 154ffb592..024cec504 100644 --- a/src/pages/wallet/NetWorth.tsx +++ b/src/pages/wallet/NetWorth.tsx @@ -12,10 +12,13 @@ import { capitalize } from "@mui/material" import NetWorthTooltip from "./NetWorthTooltip" import { ModalButton } from "components/feedback" import FiatRampModal from "./FiatRampModal" -import { Add as AddIcon, Send as SendIcon } from "@mui/icons-material" +// import { Add as AddIcon, Send as SendIcon } from "@mui/icons-material" import classNames from "classnames" import { useInterchainAddresses } from "auth/hooks/useAddress" import { useNetworkName } from "data/wallet" +import { ReactComponent as SendIcon } from "styles/images/icons/Send_v2.svg" +import { ReactComponent as ReceiveIcon } from "styles/images/icons/Receive_v2.svg" +import { ReactComponent as AddIcon } from "styles/images/icons/Buy_v2.svg" const cx = classNames.bind(styles) @@ -47,12 +50,20 @@ const NetWorth = () => {

{currency.symbol}{" "} - +

{capitalize(t("receive"))}

@@ -82,7 +94,7 @@ const NetWorth = () => { ( - )} diff --git a/src/pages/wallet/SendPage.tsx b/src/pages/wallet/SendPage.tsx index 7c4323254..c5f7533d3 100644 --- a/src/pages/wallet/SendPage.tsx +++ b/src/pages/wallet/SendPage.tsx @@ -272,7 +272,8 @@ const SendPage = () => { addresses[token?.chain ?? ""], address, undefined, - (Date.now() + 120 * 1000) * 1e6 + (Date.now() + 120 * 1000) * 1e6, + undefined ), ] diff --git a/src/pages/wallet/TransferPage.tsx b/src/pages/wallet/TransferPage.tsx index 99ef83f33..259192694 100644 --- a/src/pages/wallet/TransferPage.tsx +++ b/src/pages/wallet/TransferPage.tsx @@ -285,7 +285,8 @@ const TransferPage = () => { addresses[token?.chain ?? ""], address, undefined, - (Date.now() + 120 * 1000) * 1e6 + (Date.now() + 120 * 1000) * 1e6, + undefined ), ] diff --git a/src/styles/images/icons/Buy_v2.svg b/src/styles/images/icons/Buy_v2.svg new file mode 100644 index 000000000..0a1f1dcfd --- /dev/null +++ b/src/styles/images/icons/Buy_v2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/styles/images/icons/ManageAssets.svg b/src/styles/images/icons/ManageAssets.svg new file mode 100644 index 000000000..dcc8892b5 --- /dev/null +++ b/src/styles/images/icons/ManageAssets.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/styles/images/icons/Receive_v2.svg b/src/styles/images/icons/Receive_v2.svg new file mode 100644 index 000000000..4403b8262 --- /dev/null +++ b/src/styles/images/icons/Receive_v2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/styles/images/icons/Send_v2.svg b/src/styles/images/icons/Send_v2.svg new file mode 100644 index 000000000..5d583b0b2 --- /dev/null +++ b/src/styles/images/icons/Send_v2.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/txs/Tx.tsx b/src/txs/Tx.tsx index 59ffe850d..ac7cd7118 100644 --- a/src/txs/Tx.tsx +++ b/src/txs/Tx.tsx @@ -130,8 +130,9 @@ function Tx(props: Props) { //network: networks, gasAdjustment: gasAdjustment * (txGasAdjustment ?? 1), estimationTxValues, - //msgs: simulationTx?.msgs.map((msg) => msg.toData(isClassic)), + msgs: simulationTx?.msgs.map((msg) => msg.toData(isClassic)["@type"]), } + const { data: estimatedGas, ...estimatedGasState } = useQuery( [queryKey.tx.create, key, isWalletEmpty], async () => { diff --git a/src/utils/chain.ts b/src/utils/chain.ts index eb9985fbe..ab2283936 100644 --- a/src/utils/chain.ts +++ b/src/utils/chain.ts @@ -1,18 +1,18 @@ -import { useBankBalance } from "data/queries/bank" -import { useNativeDenoms } from "data/token" import { useExchangeRates } from "data/queries/coingecko" import { useDisplayChains } from "./localStorage/hooks" -import { useNetworkName } from "data/wallet" import { AccAddress } from "@terra-money/feather.js" +import { useBankBalance } from "data/queries/bank" +import { useNativeDenoms } from "data/token" +import { useNetworkName } from "data/wallet" type ChainId = string type ChainPrefix = string export const isTerraChain = (id: ChainId | ChainPrefix) => - id.startsWith("phoenix-") || id.startsWith("pisco-") || id === "terra" + id?.startsWith("phoenix-") || id?.startsWith("pisco-") || id === "terra" export const isOsmosisChain = (id: ChainId | ChainPrefix) => - id.startsWith("osmosis-") || id === "osmo" + id?.startsWith("osmosis-") || id === "osmo" export const useChainsByAssetValue = () => { const coins = useBankBalance() @@ -20,12 +20,12 @@ export const useChainsByAssetValue = () => { const { data: prices } = useExchangeRates() const coinValues = coins?.map(({ amount, denom, chain }) => { - const { token, decimals, symbol } = readNativeDenom(denom) + const { token, decimals, isNonWhitelisted } = readNativeDenom(denom) return { chain, value: (parseInt(amount) * - (symbol?.endsWith("...") ? 0 : prices?.[token]?.price ?? 0)) / + (isNonWhitelisted ? 0 : prices?.[token]?.price ?? 0)) / 10 ** decimals, } })