diff --git a/packages/extension/src/languages/en.json b/packages/extension/src/languages/en.json
index cbe34241fa..e8836cd59c 100644
--- a/packages/extension/src/languages/en.json
+++ b/packages/extension/src/languages/en.json
@@ -2,9 +2,13 @@
"main.account.chart.total-balance": "Total Balance",
"main.account.chart.available-balance": "Available",
"main.account.chart.staked-balance": "Staked",
+ "main.account.chart.reward-balance": "Rewards",
"main.account.button.deposit": "Deposit",
+ "main.account.deposit.paragraph": "Add tokens to your wallet",
"main.account.button.send": "Send",
"main.account.tooltip.no-asset": "No token in your account. Deposit some tokens to send.",
+ "main.account.button.buy": "Buy",
+ "main.account.buy.paragraph": "Buy and add native tokens to your wallet",
"main.modal.select-account.title": "Select your account",
"main.modal.select-account.button.select": "Select Account",
diff --git a/packages/extension/src/languages/ko.json b/packages/extension/src/languages/ko.json
index 8f6ccb6a41..75fcd1d89d 100644
--- a/packages/extension/src/languages/ko.json
+++ b/packages/extension/src/languages/ko.json
@@ -2,9 +2,13 @@
"main.account.chart.total-balance": "총 자산",
"main.account.chart.available-balance": "전송 가능한 자산",
"main.account.chart.staked-balance": "스테이킹된 자산",
+ "main.account.chart.reward-balance": "보상",
"main.account.button.deposit": "입금",
"main.account.button.send": "보내기",
"main.account.tooltip.no-asset": "계정에 자산이 없습니다. 자산을 입금해주세요.",
+ "main.account.deposit.paragraph": "지갑에 토큰 추가",
+ "main.account.button.buy": "구입하다",
+ "main.account.buy.paragraph": "지갑에 기본 토큰 구매 및 추가",
"main.modal.select-account.title": "계정을 선택하세요",
"main.modal.select-account.button.select": "계정 선택",
diff --git a/packages/extension/src/pages/main/asset.module.scss b/packages/extension/src/pages/main/asset.module.scss
index 6a5bdeabd6..411abbf657 100644
--- a/packages/extension/src/pages/main/asset.module.scss
+++ b/packages/extension/src/pages/main/asset.module.scss
@@ -96,16 +96,33 @@
}
.progressDiv {
- background-color: #11cdef;
+ background-color: #d43bf6;
border-radius: 2px;
+ position: relative;
}
-.progress {
+.progressAvailable {
background-color: #5e72e4;
height: 20px;
border-radius: 2px;
transition: 1s ease;
transition-delay: 0.5s;
+ z-index: 2;
+ position: absolute;
+}
+
+.progressStake {
+ background-color: #11cdef;
+ height: 20px;
+ border-radius: 2px;
+ transition: 1.5s ease;
+ transition-delay: 0.5s;
+ position: static;
+ z-index: 1;
+}
+
+.hr {
+ margin: $main-card-padding 0;
}
.emptyState {
@@ -121,6 +138,11 @@
font-size: 20px;
}
+ .buyButton {
+ margin-top: 8px;
+ width: 100%;
+ }
+
img {
width: 170px;
height: 170px;
diff --git a/packages/extension/src/pages/main/asset.tsx b/packages/extension/src/pages/main/asset.tsx
index eb3a1c6fba..a08f52fab3 100644
--- a/packages/extension/src/pages/main/asset.tsx
+++ b/packages/extension/src/pages/main/asset.tsx
@@ -8,6 +8,7 @@ import styleAsset from "./asset.module.scss";
import { TxButtonView } from "./tx-button";
import walletIcon from "../../public/assets/icon/wallet.png";
import buyIcon from "../../public/assets/icon/buy.png";
+import { DepositView } from "./deposit";
export const ProgressBar = ({
width,
@@ -16,24 +17,32 @@ export const ProgressBar = ({
width: number;
data: number[];
}) => {
- const [value, setValue] = useState(0);
+ const [values, setValues] = useState([0, 0]);
useEffect(() => {
- const total = data[0] + data[1];
- const percentage = data[0] / total;
- setValue(percentage * width);
- }, [width, data[0], data[1]]);
+ const total = data[0] + data[1] + data[2];
+ const percentageAvailable = data[0] / total;
+ const percentageStake = data[1] / total;
+ setValues([percentageAvailable * width, percentageStake * width]);
+ }, [width, data[0], data[1], data[2]]);
return (
);
};
-const EmptyState: FunctionComponent = () => {
+const EmptyState = ({ denom, chainId }: { denom: string; chainId: string }) => {
return (
No funds added
@@ -41,9 +50,19 @@ const EmptyState: FunctionComponent = () => {
That’s okay, you can deposit tokens to your address or buy some.
-
+
+ {chainId == "fetchhub-4" && (
+
+
+
+ )}
);
};
@@ -75,12 +94,22 @@ export const AssetView: FunctionComponent = observer(() => {
.getQueryBech32Address(accountInfo.bech32Address)
.total.upperCase(true);
+ const rewards = queries.cosmos.queryRewards.getQueryBech32Address(
+ accountInfo.bech32Address
+ );
+
+ const stakableReward = rewards.stakableReward;
+
const stakedSum = delegated.add(unbonding);
- const total = stakable.add(stakedSum);
+ const total = stakable.add(stakedSum).add(stakableReward);
const stakablePrice = priceStore.calculatePrice(stakable, fiatCurrency);
const stakedSumPrice = priceStore.calculatePrice(stakedSum, fiatCurrency);
+ const stakableRewardPrice = priceStore.calculatePrice(
+ stakableReward,
+ fiatCurrency
+ );
const totalPrice = priceStore.calculatePrice(total, fiatCurrency);
@@ -93,6 +122,9 @@ export const AssetView: FunctionComponent = observer(() => {
stakedSumPrice
? parseFloat(stakedSumPrice.toDec().toString())
: parseFloat(stakedSum.toDec().toString()),
+ stakableRewardPrice
+ ? parseFloat(stakableRewardPrice.toDec().toString())
+ : parseFloat(stakableReward.toDec().toString()),
];
const hasBalance = totalPrice
@@ -100,7 +132,12 @@ export const AssetView: FunctionComponent = observer(() => {
: !total.toDec().isZero();
if (!hasBalance) {
- return ;
+ return (
+
+ );
}
return (
@@ -174,9 +211,25 @@ export const AssetView: FunctionComponent = observer(() => {
{stakedSum.shrink(true).maxDecimals(6).toString()}
+
+
+
+
+
+
+ {stakableReward.shrink(true).maxDecimals(6).toString()}
+
+
+
+
);
});
diff --git a/packages/extension/src/pages/main/deposit.module.scss b/packages/extension/src/pages/main/deposit.module.scss
new file mode 100644
index 0000000000..6a91d12df8
--- /dev/null
+++ b/packages/extension/src/pages/main/deposit.module.scss
@@ -0,0 +1,44 @@
+@import "../../styles/var";
+
+.container-inner {
+ display: flex;
+ flex-direction: row;
+
+ height: 48px;
+ justify-content: center;
+ align-items: center;
+
+ .paragraph-main {
+ line-height: 1.35;
+ }
+
+ .paragraph-sub {
+ line-height: 1.35;
+ color: #8898aa;
+ }
+
+ .vertical {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .button {
+ min-width: 76px;
+ padding: 6px 10px 4px;
+ }
+}
+
+.deposit-modal {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ .qrcode {
+ margin-bottom: 20px;
+ }
+}
+
+.hr {
+ margin: $main-card-padding 0;
+}
diff --git a/packages/extension/src/pages/main/deposit.tsx b/packages/extension/src/pages/main/deposit.tsx
new file mode 100644
index 0000000000..11e976e908
--- /dev/null
+++ b/packages/extension/src/pages/main/deposit.tsx
@@ -0,0 +1,139 @@
+import React, { useEffect, useState, FunctionComponent, useRef } from "react";
+import { Button } from "reactstrap";
+import Modal from "react-modal";
+
+import styleDeposit from "./deposit.module.scss";
+import classnames from "classnames";
+import { observer } from "mobx-react-lite";
+import { useStore } from "../../stores";
+import { FormattedMessage } from "react-intl";
+
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const QrCode = require("qrcode");
+
+const DepositModal: FunctionComponent<{
+ bech32Address: string;
+}> = ({ bech32Address }) => {
+ const qrCodeRef = useRef(null);
+
+ useEffect(() => {
+ if (qrCodeRef.current && bech32Address) {
+ QrCode.toCanvas(qrCodeRef.current, bech32Address);
+ }
+ }, [bech32Address]);
+
+ return (
+
+
Scan QR code
+
+
+ );
+};
+
+export const DepositView: FunctionComponent = observer(() => {
+ const { accountStore, chainStore } = useStore();
+
+ const accountInfo = accountStore.getAccount(chainStore.current.chainId);
+ const [isDepositOpen, setIsDepositOpen] = useState(false);
+
+ return (
+
+
+
{
+ setIsDepositOpen(false);
+ }}
+ >
+
+
+
+
+
+ {" "}
+ {chainStore.current.stakeCurrency.coinDenom.toUpperCase()}
+
+
+
+
+
+
+
+
+
+ {chainStore.current.chainId == "fetchhub-4" && (
+
+
+
+
+
+
+ {" "}
+ {chainStore.current.stakeCurrency.coinDenom.toUpperCase()}
+
+
+
+
+
+
+
+
+
+
+
+ )}
+
+ );
+});
diff --git a/packages/extension/src/pages/main/index.tsx b/packages/extension/src/pages/main/index.tsx
index 0cdbf7bd34..8cc4be1691 100644
--- a/packages/extension/src/pages/main/index.tsx
+++ b/packages/extension/src/pages/main/index.tsx
@@ -20,6 +20,7 @@ import { ChainUpdaterService } from "@keplr-wallet/background";
import { DenomHelper } from "@keplr-wallet/common";
import { Dec } from "@keplr-wallet/unit";
import bellIcon from "../../public/assets/icon/bell.png";
+import { DepositView } from "./deposit";
// import { IBCTransferView } from "./ibc-transfer";
export const MainPage: FunctionComponent = observer(() => {
@@ -118,7 +119,6 @@ export const MainPage: FunctionComponent = observer(() => {
- {chainStore.current.walletUrlForStaking ? "" : null}
{hasTokens ? (
{}
diff --git a/packages/extension/src/pages/main/tx-button.module.scss b/packages/extension/src/pages/main/tx-button.module.scss
index d040a721c7..7765a3c5f5 100644
--- a/packages/extension/src/pages/main/tx-button.module.scss
+++ b/packages/extension/src/pages/main/tx-button.module.scss
@@ -10,7 +10,7 @@
padding-left: 1rem !important;
margin-right: $layout-margin;
-
+ margin-left: 0px;
&:last-child {
margin-right: 0;
}
diff --git a/packages/extension/src/pages/main/tx-button.tsx b/packages/extension/src/pages/main/tx-button.tsx
index 45b6f46203..9fd0e71982 100644
--- a/packages/extension/src/pages/main/tx-button.tsx
+++ b/packages/extension/src/pages/main/tx-button.tsx
@@ -1,12 +1,6 @@
-import React, {
- FunctionComponent,
- useEffect,
- useMemo,
- useRef,
- useState,
-} from "react";
+import React, { FunctionComponent, useMemo, useState } from "react";
-import { Button, Tooltip } from "reactstrap";
+import { Button } from "reactstrap";
import styleTxButton from "./tx-button.module.scss";
@@ -14,7 +8,7 @@ import { observer } from "mobx-react-lite";
import { useStore } from "../../stores";
-import Modal from "react-modal";
+import { useNotification } from "../../components/notification";
import { FormattedMessage } from "react-intl";
import { useHistory } from "react-router";
@@ -23,41 +17,21 @@ import { Dec } from "@keplr-wallet/unit";
import classnames from "classnames";
import send from "../../public/assets/icon/send.png";
-import swap from "../../public/assets/icon/swap.png";
+import reward from "../../public/assets/icon/reward.png";
import stake from "../../public/assets/icon/stake.png";
import activeSend from "../../public/assets/icon/activeSend.png";
-import activeSwap from "../../public/assets/icon/activeSwap.png";
+import activeReward from "../../public/assets/icon/activeReward.png";
import activeStake from "../../public/assets/icon/activeStake.png";
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const QrCode = require("qrcode");
-
-const DepositModal: FunctionComponent<{
- bech32Address: string;
-}> = ({ bech32Address }) => {
- const qrCodeRef = useRef(null);
-
- useEffect(() => {
- if (qrCodeRef.current && bech32Address) {
- QrCode.toCanvas(qrCodeRef.current, bech32Address);
- }
- }, [bech32Address]);
-
- return (
-
-
Scan QR code
-
-
- );
-};
-
export const TxButtonView: FunctionComponent = observer(() => {
const { accountStore, chainStore, queriesStore, analyticsStore } = useStore();
+ const notification = useNotification();
+
const [isActiveSend, setIsActiveSend] = useState(false);
const [isActiveStake, setIsActiveStake] = useState(false);
- const [isActiveSwap, setIsActiveSwap] = useState(false);
+ const [isActiveReward, setIsActiveReward] = useState(false);
const accountInfo = accountStore.getAccount(chainStore.current.chainId);
const queries = queriesStore.get(chainStore.current.chainId);
@@ -65,17 +39,12 @@ export const TxButtonView: FunctionComponent = observer(() => {
accountInfo.bech32Address
);
- const [isDepositOpen, setIsDepositOpen] = useState(false);
-
- const [sendTooltipOpen, setSendTooltipOpen] = useState(false);
- const [stakeTooltipOpen, setStakeTooltipOpen] = useState(false);
const history = useHistory();
const hasAssets =
queryBalances.balances.find((bal) => bal.balance.toDec().gt(new Dec(0))) !==
undefined;
- const sendBtnRef = useRef(null);
const rewards = queries.cosmos.queryRewards.getQueryBech32Address(
accountInfo.bech32Address
);
@@ -84,37 +53,55 @@ export const TxButtonView: FunctionComponent = observer(() => {
accountInfo.bech32Address
).stakable;
- const isRewardExist = rewards.rewards.length > 0;
+ const isRewardExist = rewards.stakableReward.toDec().gt(new Dec(0));
const isStakableExist = useMemo(() => {
return stakable.balance.toDec().gt(new Dec(0));
}, [stakable.balance]);
- const stakeBtnRef = useRef(null);
- return (
-
-
{
+ if (accountInfo.isReadyToSendMsgs) {
+ try {
+ // When the user delegated too many validators,
+ // it can't be sent to withdraw rewards from all validators due to the block gas limit.
+ // So, to prevent this problem, just send the msgs up to 8.
+ await accountInfo.cosmos.sendWithdrawDelegationRewardMsgs(
+ rewards.getDescendingPendingRewardValidatorAddresses(8),
+ "",
+ undefined,
+ undefined,
+ {
+ onBroadcasted: () => {
+ analyticsStore.logEvent("Claim reward tx broadcasted", {
+ chainId: chainStore.current.chainId,
+ chainName: chainStore.current.chainName,
+ });
+ },
+ }
+ );
+
+ history.replace("/");
+ } catch (e: any) {
+ history.replace("/");
+ notification.push({
+ type: "warning",
+ placement: "top-center",
+ duration: 5,
+ content: `Fail to withdraw rewards: ${e.message}`,
+ canDelete: true,
+ transition: {
+ duration: 0.25,
},
- }}
- isOpen={isDepositOpen}
- onRequestClose={() => {
- setIsDepositOpen(false);
- }}
- >
-
-
+ });
+ }
+ }
+ };
+ return (
+
);
diff --git a/packages/extension/src/public/assets/icon/activeReward.png b/packages/extension/src/public/assets/icon/activeReward.png
new file mode 100644
index 0000000000..56d5deef01
Binary files /dev/null and b/packages/extension/src/public/assets/icon/activeReward.png differ
diff --git a/packages/extension/src/public/assets/icon/reward.png b/packages/extension/src/public/assets/icon/reward.png
new file mode 100644
index 0000000000..5a3fc6569a
Binary files /dev/null and b/packages/extension/src/public/assets/icon/reward.png differ
diff --git a/packages/extension/src/styles/global.scss b/packages/extension/src/styles/global.scss
index d2d559ce51..a3f70ba12f 100644
--- a/packages/extension/src/styles/global.scss
+++ b/packages/extension/src/styles/global.scss
@@ -1,5 +1,9 @@
@charset "utf-8";
+$theme-colors: (
+ "primary": #3b82f6,
+);
+
@import "../../../../node_modules/argon-dashboard-react/src/assets/plugins/nucleo/css/nucleo.css";
$fa-font-path: "~@fortawesome/fontawesome-free/webfonts";