-
- {evmRenderedMessage ? (
- evmRenderedMessage
- ) : (
-
- {origin ?? "Unknown"}
-
- )}
-
- {!evmRenderedMessage && (
-
-
- Message
-
-
-
- Requested Network
-
-
-
{chainStore.current.chainName}
-
-
- )}
-
- );
-});
diff --git a/packages/fetch-extension/src/pages/sign/amino.tsx b/packages/fetch-extension/src/pages/sign/amino.tsx
deleted file mode 100644
index b7803e6038..0000000000
--- a/packages/fetch-extension/src/pages/sign/amino.tsx
+++ /dev/null
@@ -1,186 +0,0 @@
-/* eslint-disable react/display-name */
-
-import {
- CosmosMsgOpts,
- CosmwasmMsgOpts,
- SecretMsgOpts,
-} from "@keplr-wallet/stores";
-import { Currency } from "@keplr-wallet/types";
-import { FormattedMessage, IntlShape } from "react-intl";
-import React from "react";
-import { Bech32Address } from "@keplr-wallet/cosmos";
-import { Hash } from "@keplr-wallet/crypto";
-import {
- MessageObj,
- MsgBeginRedelegate,
- MsgDelegate,
- MsgExecuteContract,
- MsgInstantiateContract,
- MsgLink,
- MsgSend,
- MsgTransfer,
- MsgUndelegate,
- MsgVote,
- MsgWithdrawDelegatorReward,
- renderMsgBeginRedelegate,
- renderMsgDelegate,
- renderMsgExecuteContract,
- renderMsgInstantiateContract,
- renderMsgSend,
- renderMsgTransfer,
- renderMsgUndelegate,
- renderMsgVote,
- renderMsgWithdrawDelegatorReward,
- renderUnknownMessage,
-} from "./messages";
-
-export function renderAminoMessage(
- msgOpts: {
- readonly cosmos: {
- readonly msgOpts: CosmosMsgOpts;
- };
- readonly cosmwasm: {
- readonly msgOpts: CosmwasmMsgOpts;
- };
- readonly secret: {
- readonly msgOpts: SecretMsgOpts;
- };
- },
- msg: MessageObj,
- currencies: Currency[],
- intl: IntlShape
-): {
- icon: string | undefined;
- title: string;
- content: React.ReactElement;
-} {
- try {
- if (msg.type === msgOpts.cosmos.msgOpts.send.native.type) {
- const value = msg.value as MsgSend["value"];
- return renderMsgSend(currencies, intl, value.amount, value.to_address);
- }
-
- if (msg.type === msgOpts.cosmos.msgOpts.ibcTransfer.type) {
- const value = msg.value as MsgTransfer["value"];
- return renderMsgTransfer(
- currencies,
- intl,
- value.token,
- value.receiver,
- value.source_channel
- );
- }
-
- if (msg.type === msgOpts.cosmos.msgOpts.redelegate.type) {
- const value = msg.value as MsgBeginRedelegate["value"];
- return renderMsgBeginRedelegate(
- currencies,
- intl,
- value.amount,
- value.validator_src_address,
- value.validator_dst_address
- );
- }
-
- if (msg.type === msgOpts.cosmos.msgOpts.undelegate.type) {
- const value = msg.value as MsgUndelegate["value"];
- return renderMsgUndelegate(
- currencies,
- intl,
- value.amount,
- value.validator_address
- );
- }
-
- if (msg.type === msgOpts.cosmos.msgOpts.delegate.type) {
- const value = msg.value as MsgDelegate["value"];
- return renderMsgDelegate(
- currencies,
- intl,
- value.amount,
- value.validator_address
- );
- }
-
- if (msg.type === msgOpts.cosmos.msgOpts.withdrawRewards.type) {
- const value = msg.value as MsgWithdrawDelegatorReward["value"];
- return renderMsgWithdrawDelegatorReward(intl, value.validator_address);
- }
-
- if (msg.type === msgOpts.cosmos.msgOpts.govVote.type) {
- const value = msg.value as MsgVote["value"];
- return renderMsgVote(intl, value.proposal_id, value.option);
- }
-
- if (msg.type === "wasm/MsgInstantiateContract") {
- const value = msg.value as MsgInstantiateContract["value"];
- return renderMsgInstantiateContract(
- currencies,
- intl,
- value.init_funds,
- value.admin,
- value.code_id,
- value.label,
- value.init_msg
- );
- }
-
- if (
- msg.type === msgOpts.cosmwasm.msgOpts.executeWasm.type ||
- msg.type === msgOpts.secret.msgOpts.executeSecretWasm.type
- ) {
- const value = msg.value as MsgExecuteContract["value"];
- return renderMsgExecuteContract(
- currencies,
- intl,
- value.funds ?? value.sent_funds ?? [],
- value.callback_code_hash,
- value.contract,
- value.msg
- );
- }
-
- if (msg.type === "cyber/Link") {
- const value = msg.value as MsgLink["value"];
-
- const cyberlinks: { from: string; to: string }[] = [];
-
- for (const link of value.links) {
- cyberlinks.push({
- from: link.from,
- to: link.to,
- });
- }
-
- return {
- icon: "fas fa-paper-plane",
- title: intl.formatMessage({
- id: "sign.list.message.cyber/Link.title",
- }),
- content: (
- {chunks} ,
- br: ,
- neuron: Bech32Address.shortenAddress(value.neuron, 20),
- link: cyberlinks
- .map((link) => {
- return `${Hash.truncHashPortion(
- link.from,
- 7,
- 7
- )} → ${Hash.truncHashPortion(link.to, 7, 7)}`;
- })
- .join(", "),
- }}
- />
- ),
- };
- }
- } catch (e) {
- console.log(e);
- }
-
- return renderUnknownMessage(msg);
-}
diff --git a/packages/fetch-extension/src/pages/sign/data-tab.tsx b/packages/fetch-extension/src/pages/sign/data-tab.tsx
deleted file mode 100644
index 049f18f1d3..0000000000
--- a/packages/fetch-extension/src/pages/sign/data-tab.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React, { FunctionComponent } from "react";
-import { observer } from "mobx-react-lite";
-import { SignDocHelper } from "@keplr-wallet/hooks";
-
-import style from "./style.module.scss";
-import { EthSignType } from "@keplr-wallet/types";
-
-export const DataTab: FunctionComponent<{
- signDocHelper: SignDocHelper;
- ethSignType?: EthSignType;
-}> = observer(({ signDocHelper, ethSignType }) => {
- if (
- ethSignType === EthSignType.TRANSACTION &&
- signDocHelper.signDocWrapper &&
- signDocHelper.signDocWrapper.mode === "amino" &&
- signDocHelper.signDocWrapper.aminoSignDoc.msgs.length === 1 &&
- signDocHelper.signDocWrapper.aminoSignDoc.msgs[0].type ===
- "sign/MsgSignData"
- ) {
- const decoder = new TextDecoder();
- const jsonStr = decoder.decode(
- Buffer.from(
- signDocHelper.signDocWrapper.aminoSignDoc.msgs[0].value.data,
- "base64"
- )
- );
- const ethPayload = JSON.stringify(JSON.parse(jsonStr), undefined, 2);
- return {ethPayload} ;
- }
-
- const content = JSON.stringify(signDocHelper.signDocJson, undefined, 2);
- return {content} ;
-});
diff --git a/packages/fetch-extension/src/pages/sign/decimals.spec.ts b/packages/fetch-extension/src/pages/sign/decimals.spec.ts
deleted file mode 100644
index 12a29beb84..0000000000
--- a/packages/fetch-extension/src/pages/sign/decimals.spec.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { clearDecimals } from "./decimals";
-
-describe("clearDecimals", () => {
- it("should return the input string if it does not contain a decimal point", () => {
- const input = "1234";
- expect(clearDecimals(input)).toBe(input);
- });
-
- it("should remove trailing zeros after the decimal point", () => {
- const input = "1234.0000";
- const expected = "1234";
- expect(clearDecimals(input)).toBe(expected);
- });
-
- it("should remove the decimal point if the last character is a dot", () => {
- const input = "1234.";
- const expected = "1234";
- expect(clearDecimals(input)).toBe(expected);
- });
-
- it("should remove trailing zeros and the decimal point if both are present", () => {
- const input = "12.340000";
- const expected = "12.34";
- expect(clearDecimals(input)).toBe(expected);
- });
-
- it("should handle decimals with no trailing zeros", () => {
- const input = "12.34";
- expect(clearDecimals(input)).toBe(input);
- });
-
- it("should handle input with multiple decimal points", () => {
- const input = "12.34.56.000";
- const expected = "12.34.56";
- expect(clearDecimals(input)).toBe(expected);
- });
-
- it("should handle an empty string input", () => {
- const input = "";
- expect(clearDecimals(input)).toBe(input);
- });
-});
diff --git a/packages/fetch-extension/src/pages/sign/decimals.ts b/packages/fetch-extension/src/pages/sign/decimals.ts
deleted file mode 100644
index ee0f9aaa97..0000000000
--- a/packages/fetch-extension/src/pages/sign/decimals.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-export function clearDecimals(dec: string): string {
- if (!dec.includes(".")) {
- return dec;
- }
-
- for (let i = dec.length - 1; i >= 0; i--) {
- if (dec[i] === "0") {
- dec = dec.slice(0, dec.length - 1);
- } else {
- break;
- }
- }
- if (dec.length > 0 && dec[dec.length - 1] === ".") {
- dec = dec.slice(0, dec.length - 1);
- }
-
- return dec;
-}
diff --git a/packages/fetch-extension/src/pages/sign/details-tab.module.scss b/packages/fetch-extension/src/pages/sign/details-tab.module.scss
deleted file mode 100644
index 03f53c1053..0000000000
--- a/packages/fetch-extension/src/pages/sign/details-tab.module.scss
+++ /dev/null
@@ -1,76 +0,0 @@
-.hr {
- background-color: gray;
- margin: 0;
- height: 1px;
-}
-
-.container {
- flex: 1;
- display: flex;
- flex-direction: column;
-}
-
-.msgContainer {
- flex: 1;
-
- hr {
- margin: 8px 0;
- }
-
- .msg {
- display: flex;
- flex-direction: row;
-
- .icon {
- display: flex;
- flex-direction: column;
- margin: 0 10px 0 8px;
- width: 24px;
- text-align: center;
-
- i {
- font-size: 20px;
- line-height: 20px;
- }
- }
-
- .contentContainer {
- display: flex;
- flex: 1;
- flex-direction: column;
-
- .contentTitle {
- font-size: 16px;
- font-weight: bold;
- }
-
- .content {
- font-size: 12px;
- color: gray;
- }
- }
- }
-}
-
-.ethLedgerBlindSigningWarning {
- padding: 20px 0;
- background: #f7f9fc;
- border-radius: 6px;
-
- .title {
- font-weight: 600;
- font-size: 14px;
- line-height: 20px;
- color: #323c4a;
- margin-bottom: 10px;
- margin-left: 28px;
- }
-
- .list {
- font-size: 14px;
- line-height: 20px;
- color: #566172;
- padding-inline-start: 36px;
- margin-bottom: 0;
- }
-}
diff --git a/packages/fetch-extension/src/pages/sign/details-tab.tsx b/packages/fetch-extension/src/pages/sign/details-tab.tsx
deleted file mode 100644
index 8528e99872..0000000000
--- a/packages/fetch-extension/src/pages/sign/details-tab.tsx
+++ /dev/null
@@ -1,252 +0,0 @@
-import React, { FunctionComponent } from "react";
-
-import { observer } from "mobx-react-lite";
-import { useStore } from "../../stores";
-
-import styleDetailsTab from "./details-tab.module.scss";
-
-import { renderAminoMessage } from "./amino";
-import { Msg } from "@keplr-wallet/types";
-import { FormattedMessage, useIntl } from "react-intl";
-import { FeeButtons, MemoInput } from "@components/form";
-import {
- IFeeConfig,
- IGasConfig,
- IMemoConfig,
- SignDocHelper,
-} from "@keplr-wallet/hooks";
-import { useLanguage } from "../../languages";
-import { Badge, Button, Label } from "reactstrap";
-import { renderDirectMessage } from "./direct";
-import { AnyWithUnpacked } from "@keplr-wallet/cosmos";
-import { CoinPretty } from "@keplr-wallet/unit";
-
-export const DetailsTab: FunctionComponent<{
- signDocHelper: SignDocHelper;
- memoConfig: IMemoConfig;
- feeConfig: IFeeConfig;
- gasConfig: IGasConfig;
-
- isInternal: boolean;
-
- preferNoSetFee: boolean;
- preferNoSetMemo: boolean;
-
- isNeedLedgerEthBlindSigning: boolean;
-}> = observer(
- ({
- signDocHelper,
- memoConfig,
- feeConfig,
- gasConfig,
- isInternal,
- preferNoSetFee,
- preferNoSetMemo,
- isNeedLedgerEthBlindSigning,
- }) => {
- const { chainStore, priceStore, accountStore } = useStore();
- const intl = useIntl();
- const language = useLanguage();
-
- const mode = signDocHelper.signDocWrapper
- ? signDocHelper.signDocWrapper.mode
- : "none";
- const msgs = signDocHelper.signDocWrapper
- ? signDocHelper.signDocWrapper.mode === "amino"
- ? signDocHelper.signDocWrapper.aminoSignDoc.msgs
- : signDocHelper.signDocWrapper.protoSignDoc.txMsgs
- : [];
-
- const renderedMsgs = (() => {
- if (mode === "amino") {
- return (msgs as readonly Msg[]).map((msg, i) => {
- const msgContent = renderAminoMessage(
- accountStore.getAccount(chainStore.current.chainId),
- msg,
- chainStore.current.currencies,
- intl
- );
- return (
-
-
- {msgContent.content}
-
-
-
- );
- });
- } else if (mode === "direct") {
- return (msgs as AnyWithUnpacked[]).map((msg, i) => {
- const msgContent = renderDirectMessage(
- msg,
- chainStore.current.currencies,
- intl
- );
- return (
-
-
- {msgContent.content}
-
-
-
- );
- });
- } else {
- return null;
- }
- })();
-
- return (
-
-
-
-
- {msgs.length}
-
-
-
- {renderedMsgs}
-
-
- {!preferNoSetMemo ? (
-
- ) : (
-
-
-
-
-
-
- {memoConfig.memo
- ? memoConfig.memo
- : intl.formatMessage({ id: "sign.info.warning.empty-memo" })}
-
-
-
- )}
- {!preferNoSetFee || !feeConfig.isManual ? (
-
- ) : (
-
-
-
-
-
-
- {(() => {
- // To modify the gas in the current component composition,
- // the fee buttons component should be shown.
- // However, if the fee amount is an empty array, the UI to show is ambiguous.
- // Therefore, if the fee amount is an empty array, it is displayed as 0 fee in some asset.
- const feeOrZero =
- feeConfig.fee ??
- (() => {
- if (chainStore.current.feeCurrencies.length === 0) {
- return new CoinPretty(
- chainStore.current.stakeCurrency,
- "0"
- );
- }
-
- return new CoinPretty(
- chainStore.current.feeCurrencies[0],
- "0"
- );
- })();
-
- return (
-
- {feeOrZero.maxDecimals(6).trim(true).toString()}
- {priceStore.calculatePrice(
- feeOrZero,
- language.fiatCurrency
- ) ? (
-
- {priceStore
- .calculatePrice(feeOrZero, language.fiatCurrency)
- ?.toString()}
-
- ) : null}
-
- );
- })()}
-
-
- {
- /*
- Even if the "preferNoSetFee" option is turned on, it provides the way to edit the fee to users.
- However, if the interaction is internal, you can be sure that the fee is set well inside Keplr.
- Therefore, the button is not shown in this case.
- */
- !isInternal ? (
-
- {
- e.preventDefault();
- feeConfig.setFeeType("average");
- }}
- >
-
-
-
- ) : null
- }
-
- )}
- {isNeedLedgerEthBlindSigning ? (
-
-
- Before you click ‘Approve’
-
-
- Connect your Ledger device and select the Ethereum app
- Enable ‘blind signing’ on your Ledger device
-
-
- ) : null}
-
- );
- }
-);
-
-export const MsgRender: FunctionComponent<{
- icon?: string;
- title: string;
-}> = ({ icon = "fas fa-question", title, children }) => {
- return (
-
- );
-};
diff --git a/packages/fetch-extension/src/pages/sign/direct.tsx b/packages/fetch-extension/src/pages/sign/direct.tsx
deleted file mode 100644
index 4f23cf915c..0000000000
--- a/packages/fetch-extension/src/pages/sign/direct.tsx
+++ /dev/null
@@ -1,197 +0,0 @@
-import { Currency } from "@keplr-wallet/types";
-import { IntlShape } from "react-intl";
-import { AnyWithUnpacked, UnknownMessage } from "@keplr-wallet/cosmos";
-import {
- renderGenericMsgGrant,
- renderMsgBeginRedelegate,
- renderMsgDelegate,
- renderMsgExecuteContract,
- renderMsgInstantiateContract,
- renderMsgRevoke,
- renderMsgSend,
- renderMsgTransfer,
- renderMsgUndelegate,
- renderMsgVote,
- renderMsgWithdrawDelegatorReward,
- renderSendMsgGrant,
- renderStakeMsgGrant,
- renderUnknownMessage,
-} from "./messages";
-import { Buffer } from "buffer/";
-import { MsgSend } from "@keplr-wallet/proto-types/cosmos/bank/v1beta1/tx";
-import {
- MsgBeginRedelegate,
- MsgDelegate,
- MsgUndelegate,
-} from "@keplr-wallet/proto-types/cosmos/staking/v1beta1/tx";
-import { MsgVote } from "@keplr-wallet/proto-types/cosmos/gov/v1beta1/tx";
-import { MsgWithdrawDelegatorReward } from "@keplr-wallet/proto-types/cosmos/distribution/v1beta1/tx";
-import {
- MsgExecuteContract,
- MsgInstantiateContract,
-} from "@keplr-wallet/proto-types/cosmwasm/wasm/v1/tx";
-import { MsgTransfer } from "@keplr-wallet/proto-types/ibc/applications/transfer/v1/tx";
-import {
- MsgGrant,
- MsgRevoke,
-} from "@keplr-wallet/proto-types/cosmos/authz/v1beta1/tx";
-import { GenericAuthorization } from "@keplr-wallet/proto-types/cosmos/authz/v1beta1/authz";
-import { SendAuthorization } from "@keplr-wallet/proto-types/cosmos/bank/v1beta1/authz";
-import { StakeAuthorization } from "@keplr-wallet/proto-types/cosmos/staking/v1beta1/authz";
-
-export function renderDirectMessage(
- msg: AnyWithUnpacked,
- currencies: Currency[],
- intl: IntlShape
-) {
- try {
- if (msg instanceof UnknownMessage) {
- return renderUnknownMessage(msg.toJSON());
- }
-
- if ("unpacked" in msg) {
- switch (msg.typeUrl) {
- case "/cosmos.bank.v1beta1.MsgSend": {
- const sendMsg = msg.unpacked as MsgSend;
- return renderMsgSend(
- currencies,
- intl,
- sendMsg.amount,
- sendMsg.toAddress
- );
- }
- case "/cosmos.staking.v1beta1.MsgDelegate": {
- const delegateMsg = msg.unpacked as MsgDelegate;
- if (delegateMsg.amount) {
- return renderMsgDelegate(
- currencies,
- intl,
- delegateMsg.amount,
- delegateMsg.validatorAddress
- );
- }
- break;
- }
- case "/cosmos.staking.v1beta1.MsgBeginRedelegate": {
- const redelegateMsg = msg.unpacked as MsgBeginRedelegate;
- if (redelegateMsg.amount) {
- return renderMsgBeginRedelegate(
- currencies,
- intl,
- redelegateMsg.amount,
- redelegateMsg.validatorSrcAddress,
- redelegateMsg.validatorDstAddress
- );
- }
- break;
- }
- case "/cosmos.staking.v1beta1.MsgUndelegate": {
- const undelegateMsg = msg.unpacked as MsgUndelegate;
- if (undelegateMsg.amount) {
- return renderMsgUndelegate(
- currencies,
- intl,
- undelegateMsg.amount,
- undelegateMsg.validatorAddress
- );
- }
- break;
- }
- case "/cosmwasm.wasm.v1.MsgInstantiateContract": {
- const instantiateContractMsg = msg.unpacked as MsgInstantiateContract;
- return renderMsgInstantiateContract(
- currencies,
- intl,
- instantiateContractMsg.funds,
- instantiateContractMsg.admin,
- instantiateContractMsg.codeId,
- instantiateContractMsg.label,
- JSON.parse(Buffer.from(instantiateContractMsg.msg).toString())
- );
- }
- case "/cosmwasm.wasm.v1.MsgExecuteContract": {
- const executeContractMsg = msg.unpacked as MsgExecuteContract;
- return renderMsgExecuteContract(
- currencies,
- intl,
- executeContractMsg.funds,
- undefined,
- executeContractMsg.contract,
- JSON.parse(Buffer.from(executeContractMsg.msg).toString())
- );
- }
- case "/cosmos.authz.v1beta1.MsgGrant": {
- const grantMsg = msg.unpacked as MsgGrant;
-
- switch (grantMsg.grant?.authorization?.typeUrl) {
- case "/cosmos.bank.v1beta1.SendAuthorization":
- return renderSendMsgGrant(
- currencies,
- intl,
- grantMsg.grantee,
- grantMsg.grant.expiration,
- SendAuthorization.decode(grantMsg.grant.authorization.value)
- );
-
- case "/cosmos.staking.v1beta1.StakeAuthorization":
- return renderStakeMsgGrant(
- currencies,
- intl,
- grantMsg.grantee,
- grantMsg.grant.expiration,
- StakeAuthorization.decode(grantMsg.grant?.authorization.value)
- );
-
- default:
- return renderGenericMsgGrant(
- intl,
- grantMsg.grantee,
- grantMsg.grant?.expiration,
- grantMsg.grant?.authorization?.typeUrl ===
- "/cosmos.authz.v1beta1.GenericAuthorization"
- ? GenericAuthorization.decode(
- grantMsg.grant!.authorization!.value
- ).msg
- : grantMsg.grant!.authorization!.typeUrl
- );
- }
- }
- case "/cosmos.authz.v1beta1.MsgRevoke": {
- const revokeMsg = msg.unpacked as MsgRevoke;
- return renderMsgRevoke(intl, revokeMsg.msgTypeUrl, revokeMsg.grantee);
- }
- case "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward": {
- const withdrawMsg = msg.unpacked as MsgWithdrawDelegatorReward;
- return renderMsgWithdrawDelegatorReward(
- intl,
- withdrawMsg.validatorAddress
- );
- }
- case "/cosmos.gov.v1beta1.MsgVote": {
- const voteMsg = msg.unpacked as MsgVote;
- return renderMsgVote(intl, voteMsg.proposalId, voteMsg.option);
- }
- case "/ibc.applications.transfer.v1.MsgTransfer": {
- const transferMsg = msg.unpacked as MsgTransfer;
- if (transferMsg.token) {
- return renderMsgTransfer(
- currencies,
- intl,
- transferMsg.token,
- transferMsg.receiver,
- transferMsg.sourceChannel
- );
- }
- break;
- }
- }
- }
- } catch (e) {
- console.log(e);
- }
-
- return renderUnknownMessage({
- typeUrl: msg.typeUrl || "Unknown",
- value: Buffer.from(msg.value).toString("base64"),
- });
-}
diff --git a/packages/fetch-extension/src/pages/sign/evm.tsx b/packages/fetch-extension/src/pages/sign/evm.tsx
deleted file mode 100644
index abb6f8b30e..0000000000
--- a/packages/fetch-extension/src/pages/sign/evm.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-/* eslint-disable react/display-name */
-
-import { erc20MetadataInterface } from "@keplr-wallet/stores";
-import { Currency } from "@keplr-wallet/types";
-import { IntlShape } from "react-intl";
-import React from "react";
-import {
- renderMsgEvmExecuteContract,
- renderMsgSend,
- renderUnknownMessage,
-} from "./messages";
-import { UnsignedTransaction } from "@ethersproject/transactions";
-import { BigNumber } from "@ethersproject/bignumber";
-import { DenomHelper } from "@keplr-wallet/common";
-
-export function renderEvmTxn(
- txnParams: UnsignedTransaction,
- nativeCurrency: Currency,
- currencies: Currency[],
- intl: IntlShape
-): {
- icon: string | undefined;
- title: string;
- content: React.ReactElement;
-} {
- try {
- if (
- txnParams.value &&
- BigNumber.from(txnParams.value).gt(0) &&
- !txnParams.data
- ) {
- return renderMsgSend(
- currencies,
- intl,
- [
- {
- amount: BigNumber.from(txnParams.value).toString(),
- denom: nativeCurrency.coinMinimalDenom,
- },
- ],
- txnParams.to ?? "",
- true
- );
- }
-
- if (txnParams.data) {
- const sendCurrency = currencies.find((c) => {
- const coin = new DenomHelper(c.coinMinimalDenom);
- return coin.type === "erc20" && coin.contractAddress === txnParams.to;
- });
-
- if (sendCurrency) {
- const erc20TransferParams = erc20MetadataInterface.parseTransaction({
- data: txnParams.data.toString(),
- value: txnParams.value,
- });
-
- if (erc20TransferParams.name === "transfer") {
- return renderMsgSend(
- currencies,
- intl,
- [
- {
- amount: erc20TransferParams.args["_value"].toString(),
- denom: sendCurrency.coinMinimalDenom,
- },
- ],
- erc20TransferParams.args["_to"],
- true
- );
- }
- }
-
- return renderMsgEvmExecuteContract(
- intl,
- txnParams.value && BigNumber.from(txnParams.value).gt(0)
- ? {
- amount: BigNumber.from(txnParams.value).toString(),
- denom: nativeCurrency.coinMinimalDenom,
- }
- : undefined,
- txnParams
- );
- }
- } catch (e) {
- console.log(e);
- }
-
- return renderUnknownMessage(txnParams);
-}
diff --git a/packages/fetch-extension/src/pages/sign/index.tsx b/packages/fetch-extension/src/pages/sign/index.tsx
deleted file mode 100644
index 4378822519..0000000000
--- a/packages/fetch-extension/src/pages/sign/index.tsx
+++ /dev/null
@@ -1,411 +0,0 @@
-import React, { FunctionComponent, useEffect, useMemo, useState } from "react";
-import { Button } from "reactstrap";
-
-import { HeaderLayout } from "@layouts/index";
-
-import style from "./style.module.scss";
-
-import { useStore } from "../../stores";
-
-import classnames from "classnames";
-import { DataTab } from "./data-tab";
-import { DetailsTab } from "./details-tab";
-import { FormattedMessage, useIntl } from "react-intl";
-
-import { useNavigate } from "react-router";
-import { observer } from "mobx-react-lite";
-import {
- useFeeConfig,
- useInteractionInfo,
- useMemoConfig,
- useSignDocAmountConfig,
- useSignDocHelper,
- useZeroAllowedGasConfig,
-} from "@keplr-wallet/hooks";
-import { ADR36SignDocDetailsTab } from "./adr-36";
-import { ChainIdHelper } from "@keplr-wallet/cosmos";
-import { unescapeHTML } from "@keplr-wallet/common";
-import { EthSignType } from "@keplr-wallet/types";
-
-enum Tab {
- Details,
- Data,
-}
-
-export const SignPage: FunctionComponent = observer(() => {
- const navigate = useNavigate();
-
- const [tab, setTab] = useState(Tab.Details);
-
- const intl = useIntl();
-
- const {
- chainStore,
- keyRingStore,
- signInteractionStore,
- accountStore,
- queriesStore,
- analyticsStore,
- } = useStore();
-
- const [signer, setSigner] = useState("");
- const [origin, setOrigin] = useState();
- const [isADR36WithString, setIsADR36WithString] = useState<
- boolean | undefined
- >();
- const [ethSignType, setEthSignType] = useState();
-
- const current = chainStore.current;
- // There are services that sometimes use invalid tx to sign arbitrary data on the sign page.
- // In this case, there is no obligation to deal with it, but 0 gas is favorably allowed.
- const gasConfig = useZeroAllowedGasConfig(chainStore, current.chainId, 0);
- const amountConfig = useSignDocAmountConfig(
- chainStore,
- accountStore,
- current.chainId,
- signer
- );
- const feeConfig = useFeeConfig(
- chainStore,
- queriesStore,
- current.chainId,
- signer,
- amountConfig,
- gasConfig
- );
- const memoConfig = useMemoConfig(chainStore, current.chainId);
-
- const signDocHelper = useSignDocHelper(feeConfig, memoConfig);
- amountConfig.setSignDocHelper(signDocHelper);
-
- useEffect(() => {
- if (signInteractionStore.waitingData) {
- const data = signInteractionStore.waitingData;
- chainStore.selectChain(data.data.chainId);
- if (data.data.signDocWrapper.isADR36SignDoc) {
- setIsADR36WithString(data.data.isADR36WithString);
- }
- if (data.data.ethSignType) {
- setEthSignType(data.data.ethSignType);
- }
- setOrigin(data.data.msgOrigin);
- if (
- !data.data.signDocWrapper.isADR36SignDoc &&
- data.data.chainId !== data.data.signDocWrapper.chainId
- ) {
- // Validate the requested chain id and the chain id in the sign doc are same.
- // If the sign doc is for ADR-36, there is no chain id in the sign doc, so no need to validate.
- throw new Error("Chain id unmatched");
- }
- signDocHelper.setSignDocWrapper(data.data.signDocWrapper);
- gasConfig.setGas(data.data.signDocWrapper.gas);
- let memo = data.data.signDocWrapper.memo;
- if (data.data.signDocWrapper.mode === "amino") {
- // For amino-json sign doc, the memo is escaped by default behavior of golang's json marshaller.
- // For normal users, show the escaped characters with unescaped form.
- // Make sure that the actual sign doc's memo should be escaped.
- // In this logic, memo should be escaped from account store or background's request signing function.
- memo = unescapeHTML(memo);
- }
- memoConfig.setMemo(memo);
- if (
- data.data.signOptions.preferNoSetFee &&
- data.data.signDocWrapper.fees[0]
- ) {
- feeConfig.setManualFee(data.data.signDocWrapper.fees[0]);
- }
- amountConfig.setDisableBalanceCheck(
- !!data.data.signOptions.disableBalanceCheck
- );
- feeConfig.setDisableBalanceCheck(
- !!data.data.signOptions.disableBalanceCheck
- );
- if (
- data.data.signDocWrapper.granter &&
- data.data.signDocWrapper.granter !== data.data.signer
- ) {
- feeConfig.setDisableBalanceCheck(true);
- }
- setSigner(data.data.signer);
- }
- }, [
- amountConfig,
- chainStore,
- gasConfig,
- memoConfig,
- feeConfig,
- signDocHelper,
- signInteractionStore.waitingData,
- ]);
-
- // If the preferNoSetFee or preferNoSetMemo in sign options is true,
- // don't show the fee buttons/memo input by default
- // But, the sign options would be removed right after the users click the approve/reject button.
- // Thus, without this state, the fee buttons/memo input would be shown after clicking the approve buttion.
- const [isProcessing, setIsProcessing] = useState(false);
- const needSetIsProcessing =
- signInteractionStore.waitingData?.data.signOptions.preferNoSetFee ===
- true ||
- signInteractionStore.waitingData?.data.signOptions.preferNoSetMemo === true;
-
- const preferNoSetFee =
- signInteractionStore.waitingData?.data.signOptions.preferNoSetFee ===
- true || isProcessing;
- const preferNoSetMemo =
- signInteractionStore.waitingData?.data.signOptions.preferNoSetMemo ===
- true || isProcessing;
-
- const interactionInfo = useInteractionInfo(
- () => {
- if (needSetIsProcessing) {
- setIsProcessing(true);
- }
-
- signInteractionStore.rejectAll();
- },
- {
- enableScroll: true,
- }
- );
-
- const currentChainId = chainStore.current.chainId;
- const currentChainIdentifier = useMemo(
- () => ChainIdHelper.parse(currentChainId).identifier,
- [currentChainId]
- );
- const selectedChainId = chainStore.selectedChainId;
- const selectedChainIdentifier = useMemo(
- () => ChainIdHelper.parse(selectedChainId).identifier,
- [selectedChainId]
- );
-
- // Check that the request is delivered
- // and the chain is selected properly.
- // The chain store loads the saved chain infos including the suggested chain asynchronously on init.
- // So, it can be different the current chain and the expected selected chain for a moment.
- const isLoaded = (() => {
- if (!signDocHelper.signDocWrapper) {
- return false;
- }
-
- return currentChainIdentifier === selectedChainIdentifier;
- })();
-
- // If this is undefined, show the chain name on the header.
- // If not, show the alternative title.
- const alternativeTitle = (() => {
- if (!isLoaded) {
- return "";
- }
-
- if (
- signDocHelper.signDocWrapper &&
- signDocHelper.signDocWrapper.isADR36SignDoc &&
- !ethSignType
- ) {
- return "Prove Ownership";
- }
-
- return undefined;
- })();
-
- const approveIsDisabled = (() => {
- if (!isLoaded) {
- return true;
- }
-
- if (!signDocHelper.signDocWrapper) {
- return true;
- }
-
- // If the sign doc is for ADR-36,
- // there is no error related to the fee or memo...
- if (signDocHelper.signDocWrapper.isADR36SignDoc) {
- return false;
- }
-
- return memoConfig.error != null || feeConfig.error != null;
- })();
-
- return (
- {
- analyticsStore.logEvent("back_click", { pageName: "Sign" });
- navigate(-1);
- }
- : undefined
- }
- style={{ background: "white", minHeight: "100%" }}
- innerStyle={{ display: "flex", flexDirection: "column" }}
- >
- {
- /*
- Show the informations of tx when the sign data is delivered.
- If sign data not delivered yet, show the spinner alternatively.
- */
- isLoaded ? (
-
-
-
- {tab === Tab.Data ? (
-
- ) : null}
- {tab === Tab.Details ? (
- signDocHelper.signDocWrapper?.isADR36SignDoc ? (
-
- ) : (
-
- )
- ) : null}
-
-
- {keyRingStore.keyRingType === "ledger" &&
- signInteractionStore.isLoading ? (
-
- {" "}
-
-
- ) : (
-
- {
- e.preventDefault();
-
- if (needSetIsProcessing) {
- setIsProcessing(true);
- }
-
- await signInteractionStore.reject();
-
- if (
- interactionInfo.interaction &&
- !interactionInfo.interactionInternal
- ) {
- window.close();
- }
- }}
- outline
- >
- {intl.formatMessage({
- id: "sign.button.reject",
- })}
-
- {
- e.preventDefault();
-
- if (needSetIsProcessing) {
- setIsProcessing(true);
- }
-
- if (signDocHelper.signDocWrapper) {
- await signInteractionStore.approveAndWaitEnd(
- signDocHelper.signDocWrapper
- );
- }
-
- if (
- interactionInfo.interaction &&
- !interactionInfo.interactionInternal
- ) {
- window.close();
- }
- }}
- >
- {intl.formatMessage({
- id: "sign.button.approve",
- })}
-
-
- )}
-
-
- ) : (
-
-
-
- )
- }
-
- );
-});
diff --git a/packages/fetch-extension/src/pages/sign/messages.tsx b/packages/fetch-extension/src/pages/sign/messages.tsx
deleted file mode 100644
index 508b82cf6e..0000000000
--- a/packages/fetch-extension/src/pages/sign/messages.tsx
+++ /dev/null
@@ -1,839 +0,0 @@
-/* eslint-disable react/display-name */
-
-import React, { FunctionComponent, useEffect, useMemo, useState } from "react";
-import { Bech32Address } from "@keplr-wallet/cosmos";
-import { CoinUtils, Coin } from "@keplr-wallet/unit";
-import { IntlShape, FormattedMessage, useIntl } from "react-intl";
-import { Currency } from "@keplr-wallet/types";
-import { Button, Badge, Label } from "reactstrap";
-import { observer } from "mobx-react-lite";
-import { useStore } from "../../stores";
-import yaml from "js-yaml";
-
-import { Buffer } from "buffer/";
-import { CoinPrimitive } from "@keplr-wallet/stores";
-import { clearDecimals } from "./decimals";
-import { Any } from "@keplr-wallet/proto-types/google/protobuf/any";
-import { Grant } from "@keplr-wallet/proto-types/cosmos/authz/v1beta1/authz";
-import {
- AuthorizationType,
- StakeAuthorization,
-} from "@keplr-wallet/proto-types/cosmos/staking/v1beta1/authz";
-import { SendAuthorization } from "@keplr-wallet/proto-types/cosmos/bank/v1beta1/authz";
-import { UnsignedTransaction } from "@ethersproject/transactions";
-
-export interface MessageObj {
- readonly type: string;
- readonly value: unknown;
-}
-
-export interface MsgSend {
- value: {
- amount: [
- {
- amount: string;
- denom: string;
- }
- ];
- from_address: string;
- to_address: string;
- };
-}
-
-export interface MsgTransfer {
- value: {
- source_port: string;
- source_channel: string;
- token: {
- denom: string;
- amount: string;
- };
- sender: string;
- receiver: string;
- timeout_height: {
- revision_number: string | undefined;
- revision_height: string;
- };
- };
-}
-
-export interface MsgDelegate {
- value: {
- amount: {
- amount: string;
- denom: string;
- };
- delegator_address: string;
- validator_address: string;
- };
-}
-
-export interface MsgUndelegate {
- value: {
- amount: {
- amount: string;
- denom: string;
- };
- delegator_address: string;
- validator_address: string;
- };
-}
-
-export interface MsgWithdrawDelegatorReward {
- value: {
- delegator_address: string;
- validator_address: string;
- };
-}
-
-export interface MsgBeginRedelegate {
- value: {
- amount: {
- amount: string;
- denom: string;
- };
- delegator_address: string;
- validator_dst_address: string;
- validator_src_address: string;
- };
-}
-
-export interface MsgVote {
- value: {
- proposal_id: string;
- voter: string;
- // In the stargate, option would be the enum (0: empty, 1: yes, 2: abstain, 3: no, 4: no with veto).
- option: string | number;
- };
-}
-
-export interface MsgInstantiateContract {
- value: {
- // Admin field can be omitted.
- admin?: string;
- sender: string;
- code_id: string;
- label: string;
- // eslint-disable-next-line @typescript-eslint/ban-types
- init_msg: object;
- init_funds: [
- {
- amount: string;
- denom: string;
- }
- ];
- };
-}
-
-// This message can be a normal cosmwasm message or a secret-wasm message.
-export interface MsgExecuteContract {
- value: {
- contract: string;
- // If message is for secret-wasm, msg will be the base64 encoded and encrypted string.
- // eslint-disable-next-line @typescript-eslint/ban-types
- msg: object | string;
- sender: string;
- // The field is for wasm message.
- funds?: [
- {
- amount: string;
- denom: string;
- }
- ];
- // The bottom fields are for secret-wasm message.
- sent_funds?: [
- {
- amount: string;
- denom: string;
- }
- ];
- callback_code_hash?: string;
- callback_sig?: string | null;
- };
-}
-
-export interface MsgLink {
- value: {
- links: [
- {
- from: string;
- to: string;
- }
- ];
- neuron: string;
- };
-}
-
-// eslint-disable-next-line @typescript-eslint/ban-types
-export function renderUnknownMessage(msg: object) {
- return {
- icon: undefined,
- title: "Custom",
- content: (
-
-
-
- ),
- };
-}
-
-export function renderMsgSend(
- currencies: Currency[],
- intl: IntlShape,
- amount: CoinPrimitive[],
- toAddress: string,
- isEvm?: boolean
-) {
- const receives: CoinPrimitive[] = [];
- for (const coinPrimitive of amount) {
- const coin = new Coin(coinPrimitive.denom, coinPrimitive.amount);
- const parsed = CoinUtils.parseDecAndDenomFromCoin(currencies, coin);
-
- receives.push({
- amount: clearDecimals(parsed.amount),
- denom: parsed.denom,
- });
- }
-
- return {
- icon: "fas fa-paper-plane",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgSend.title",
- }),
- content: (
- {chunks} ,
- recipient: Bech32Address.shortenAddress(toAddress, 20, isEvm),
- amount: receives
- .map((coin) => {
- return `${coin.amount} ${coin.denom}`;
- })
- .join(","),
- }}
- />
- ),
- };
-}
-
-export function renderMsgTransfer(
- currencies: Currency[],
- intl: IntlShape,
- amount: CoinPrimitive,
- receiver: string,
- channelId: string
-) {
- const coin = new Coin(amount.denom, amount.amount);
- const parsed = CoinUtils.parseDecAndDenomFromCoin(currencies, coin);
-
- amount = {
- amount: clearDecimals(parsed.amount),
- denom: parsed.denom,
- };
-
- return {
- icon: "fas fa-link",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgTransfer.title",
- }),
- content: (
- {chunks} ,
- receiver: Bech32Address.shortenAddress(receiver, 20),
- amount: `${amount.amount} ${amount.denom}`,
- channel: channelId,
- }}
- />
- ),
- };
-}
-
-export function renderMsgBeginRedelegate(
- currencies: Currency[],
- intl: IntlShape,
- amount: CoinPrimitive,
- validatorSrcAddress: string,
- validatorDstAddress: string
-) {
- const parsed = CoinUtils.parseDecAndDenomFromCoin(
- currencies,
- new Coin(amount.denom, amount.amount)
- );
-
- return {
- icon: "fas fa-layer-group",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgBeginRedelegate.title",
- }),
- content: (
- {chunks} ,
- fromValidator: Bech32Address.shortenAddress(validatorSrcAddress, 24),
- toValidator: Bech32Address.shortenAddress(validatorDstAddress, 24),
- amount: `${clearDecimals(parsed.amount)} ${parsed.denom}`,
- }}
- />
- ),
- };
-}
-
-export function renderMsgUndelegate(
- currencies: Currency[],
- intl: IntlShape,
- amount: CoinPrimitive,
- validatorAddress: string
-) {
- const parsed = CoinUtils.parseDecAndDenomFromCoin(
- currencies,
- new Coin(amount.denom, amount.amount)
- );
-
- return {
- icon: "fas fa-layer-group",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgUndelegate.title",
- }),
- content: (
- {chunks} ,
- br: ,
- validator: Bech32Address.shortenAddress(validatorAddress, 24),
- amount: `${clearDecimals(parsed.amount)} ${parsed.denom}`,
- }}
- />
- ),
- };
-}
-
-export function renderMsgDelegate(
- currencies: Currency[],
- intl: IntlShape,
- amount: CoinPrimitive,
- validatorAddress: string
-) {
- const parsed = CoinUtils.parseDecAndDenomFromCoin(
- currencies,
- new Coin(amount.denom, amount.amount)
- );
-
- return {
- icon: "fas fa-layer-group",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgDelegate.title",
- }),
- content: (
- {chunks} ,
- validator: Bech32Address.shortenAddress(validatorAddress, 24),
- amount: `${clearDecimals(parsed.amount)} ${parsed.denom}`,
- }}
- />
- ),
- };
-}
-
-export function renderMsgWithdrawDelegatorReward(
- intl: IntlShape,
- validatorAddress: string
-) {
- return {
- icon: "fas fa-money-bill",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgWithdrawDelegatorReward.title",
- }),
- content: (
- {chunks} ,
- validator: Bech32Address.shortenAddress(validatorAddress, 34),
- }}
- />
- ),
- };
-}
-
-export function renderMsgVote(
- intl: IntlShape,
- proposalId: string,
- option: string | number
-) {
- const textualOption = (() => {
- if (typeof option === "string") {
- return option;
- }
-
- switch (option) {
- case 0:
- return "Empty";
- case 1:
- return "Yes";
- case 2:
- return "Abstain";
- case 3:
- return "No";
- case 4:
- return "No with veto";
- default:
- return "Unspecified";
- }
- })();
-
- return {
- icon: "fas fa-vote-yea",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgVote.title",
- }),
- content: (
- {chunks} ,
- id: proposalId,
- option: textualOption,
- }}
- />
- ),
- };
-}
-
-export function renderMsgInstantiateContract(
- currencies: Currency[],
- intl: IntlShape,
- initFunds: CoinPrimitive[],
- admin: string | undefined,
- codeId: string,
- label: string,
- // eslint-disable-next-line @typescript-eslint/ban-types
- initMsg: object
-) {
- const funds: { amount: string; denom: string }[] = [];
- for (const coinPrimitive of initFunds) {
- const coin = new Coin(coinPrimitive.denom, coinPrimitive.amount);
- const parsed = CoinUtils.parseDecAndDenomFromCoin(currencies, coin);
-
- funds.push({
- amount: clearDecimals(parsed.amount),
- denom: parsed.denom,
- });
- }
-
- return {
- icon: "fas fa-cog",
- title: intl.formatMessage({
- id: "sign.list.message.wasm/MsgInstantiateContract.title",
- }),
- content: (
-
- {chunks} ,
- br: ,
- admin: admin ? Bech32Address.shortenAddress(admin, 30) : "",
- ["only-admin-exist"]: (...chunks: any[]) => (admin ? chunks : ""),
- codeId: codeId,
- label: label,
- ["only-funds-exist"]: (...chunks: any[]) =>
- funds.length > 0 ? chunks : "",
- funds: funds
- .map((coin) => {
- return `${coin.amount} ${coin.denom}`;
- })
- .join(","),
- }}
- />
-
-
-
- ),
- };
-}
-
-export function renderMsgEvmExecuteContract(
- intl: IntlShape,
- sent: CoinPrimitive | undefined,
- // eslint-disable-next-line @typescript-eslint/ban-types
- txnParams: UnsignedTransaction
-) {
- return {
- icon: "fas fa-cog",
- title: intl.formatMessage({
- id: "sign.list.message.wasm/MsgExecuteContract.title",
- }),
- content: (
-
- {chunks} ,
- br: ,
- address: Bech32Address.shortenAddress(txnParams.to ?? "", 26, true),
- ["only-sent-exist"]: (...chunks: any[]) => (sent ? chunks : ""),
- sent: sent ? `${sent.amount} ${sent.denom}` : "",
- }}
- />
-
- Transaction Data:
-
-
- {txnParams.data?.toString()}
-
-
- ),
- };
-}
-
-export function renderMsgExecuteContract(
- currencies: Currency[],
- intl: IntlShape,
- sentFunds: CoinPrimitive[],
- callbackCodeHash: string | undefined,
- contract: string,
- // eslint-disable-next-line @typescript-eslint/ban-types
- msg: object | string
-) {
- const sent: { amount: string; denom: string }[] = [];
- for (const coinPrimitive of sentFunds) {
- const coin = new Coin(coinPrimitive.denom, coinPrimitive.amount);
- const parsed = CoinUtils.parseDecAndDenomFromCoin(currencies, coin);
-
- sent.push({
- amount: clearDecimals(parsed.amount),
- denom: parsed.denom,
- });
- }
-
- const isSecretWasm = callbackCodeHash != null;
-
- return {
- icon: "fas fa-cog",
- title: intl.formatMessage({
- id: "sign.list.message.wasm/MsgExecuteContract.title",
- }),
- content: (
-
- {chunks} ,
- br: ,
- address: Bech32Address.shortenAddress(contract, 26),
- ["only-sent-exist"]: (...chunks: any[]) =>
- sent.length > 0 ? chunks : "",
- sent: sent
- .map((coin) => {
- return `${coin.amount} ${coin.denom}`;
- })
- .join(","),
- }}
- />
- {isSecretWasm ? (
-
-
-
-
-
-
- ) : (
-
- )}
-
-
- ),
- };
-}
-
-export function renderGenericMsgGrant(
- intl: IntlShape,
- granteeAddress: string,
- expiration: Grant["expiration"],
- grantTypeUrl: Any["typeUrl"]
-) {
- return {
- icon: "fas fa-key",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgGrant.title",
- }),
- content: (
- {chunks} ,
- grantee: Bech32Address.shortenAddress(granteeAddress, 24),
- grantType: grantTypeUrl
- ? grantTypeUrl.split(".").slice(-1)[0]
- : intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgGrant.unspecified",
- }),
- expirationDate: intl.formatDate(expiration),
- }}
- />
- ),
- };
-}
-
-const stakingGrantTypes: Record = {
- [AuthorizationType.AUTHORIZATION_TYPE_DELEGATE]:
- "sign.list.message.cosmos-sdk/MsgDelegate.title",
- [AuthorizationType.AUTHORIZATION_TYPE_REDELEGATE]:
- "sign.list.message.cosmos-sdk/MsgBeginRedelegate.title",
- [AuthorizationType.AUTHORIZATION_TYPE_UNDELEGATE]:
- "sign.list.message.cosmos-sdk/MsgUndelegate.title",
- [AuthorizationType.AUTHORIZATION_TYPE_UNSPECIFIED]:
- "sign.list.message.cosmos-sdk/MsgGrant.unspecified",
- [AuthorizationType.UNRECOGNIZED]:
- "sign.list.message.cosmos-sdk/MsgGrant.unrecognized",
-};
-
-export function renderStakeMsgGrant(
- currencies: Currency[],
- intl: IntlShape,
- grantee: string,
- expiration: Grant["expiration"],
- stakingSettings: StakeAuthorization
-) {
- const parsedMaxAmount =
- stakingSettings.maxTokens &&
- CoinUtils.parseDecAndDenomFromCoin(
- currencies,
- new Coin(
- stakingSettings.maxTokens.denom,
- stakingSettings.maxTokens.amount
- )
- );
-
- return {
- icon: "fas fa-key",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgGrant.title",
- }),
- content: (
- {chunks} ,
- br: ,
- grantee: Bech32Address.shortenAddress(grantee, 24),
- grantType: intl.formatMessage({
- id: stakingGrantTypes[stakingSettings.authorizationType],
- }),
- expirationDate: intl.formatDate(expiration),
- validatorListType: intl.formatMessage({
- id: stakingSettings.allowList?.address.length
- ? "sign.list.message.cosmos-sdk/MsgGrant.staking.validatorAllowedLabel"
- : "sign.list.message.cosmos-sdk/MsgGrant.staking.validatorDeniedLabel",
- }),
- validators: intl.formatList(
- (
- stakingSettings.allowList?.address ||
- stakingSettings.denyList?.address ||
- []
- ).map((valAddress) => Bech32Address.shortenAddress(valAddress, 24))
- ),
- maxAmount: parsedMaxAmount
- ? `${clearDecimals(parsedMaxAmount.amount)} ${
- parsedMaxAmount.denom
- }`
- : intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgGrant.unlimited",
- }),
- }}
- />
- ),
- };
-}
-
-export function renderSendMsgGrant(
- currencies: Currency[],
- intl: IntlShape,
- granteeAddress: string,
- expiration: Grant["expiration"],
- sendSettings: SendAuthorization
-) {
- const maxAmount =
- intl.formatList(
- sendSettings.spendLimit
- ?.map((amount) =>
- CoinUtils.parseDecAndDenomFromCoin(
- currencies,
- new Coin(amount.denom, amount.amount)
- )
- )
- ?.map((coin) => `${clearDecimals(coin.amount)} ${coin.denom}`)
- ) ||
- intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgGrant.unlimited",
- });
-
- return {
- icon: "fas fa-key",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgGrant.title",
- }),
- content: (
- {chunks} ,
- br: ,
- grantee: Bech32Address.shortenAddress(granteeAddress, 24),
- maxAmount,
- expirationDate: intl.formatDate(expiration),
- }}
- />
- ),
- };
-}
-
-export function renderMsgRevoke(
- intl: IntlShape,
- revokeType: string,
- granteeAddress: string
-) {
- return {
- icon: "fas fa-lock",
- title: intl.formatMessage({
- id: "sign.list.message.cosmos-sdk/MsgRevoke.title",
- }),
- content: (
- {chunks} ,
- revokeType: revokeType.split(".").slice(-1)[0],
- grantee: Bech32Address.shortenAddress(granteeAddress, 24),
- }}
- />
- ),
- };
-}
-
-export const WasmExecutionMsgView: FunctionComponent<{
- // eslint-disable-next-line @typescript-eslint/ban-types
- msg: object | string;
-}> = observer(({ msg }) => {
- const { chainStore, accountStore } = useStore();
-
- const [isOpen, setIsOpen] = useState(true);
- const intl = useIntl();
-
- const toggleOpen = () => setIsOpen((isOpen) => !isOpen);
-
- const [detailsMsg, setDetailsMsg] = useState(() =>
- JSON.stringify(msg, null, 2)
- );
- const [warningMsg, setWarningMsg] = useState("");
-
- useEffect(() => {
- // If msg is string, it will be the message for secret-wasm.
- // So, try to decrypt.
- // But, if this msg is not encrypted via Keplr, Keplr cannot decrypt it.
- // TODO: Handle the error case. If an error occurs, rather than rejecting the signing, it informs the user that Keplr cannot decrypt it and allows the user to choose.
- if (typeof msg === "string") {
- (async () => {
- try {
- let cipherText = Buffer.from(Buffer.from(msg, "base64"));
- // Msg is start with 32 bytes nonce and 32 bytes public key.
- const nonce = cipherText.slice(0, 32);
- cipherText = cipherText.slice(64);
-
- const keplr = await accountStore
- .getAccount(chainStore.current.chainId)
- .getKeplr();
- if (!keplr) {
- throw new Error("Can't get the keplr API");
- }
-
- const enigmaUtils = keplr.getEnigmaUtils(chainStore.current.chainId);
- let plainText = Buffer.from(
- await enigmaUtils.decrypt(cipherText, nonce)
- );
- // Remove the contract code hash.
- plainText = plainText.slice(64);
-
- setDetailsMsg(
- JSON.stringify(JSON.parse(plainText.toString()), null, 2)
- );
- setWarningMsg("");
- } catch {
- setWarningMsg(
- intl.formatMessage({
- id: "sign.list.message.wasm/MsgExecuteContract.content.warning.secret-wasm.failed-decryption",
- })
- );
- }
- })();
- }
- }, [chainStore, chainStore.current.chainId, intl, msg]);
-
- return (
-
- {isOpen ? (
-
- {isOpen ? detailsMsg : ""}
- {warningMsg ? {warningMsg}
: null}
-
- ) : null}
-
{
- e.preventDefault();
- e.stopPropagation();
-
- toggleOpen();
- }}
- >
- {isOpen
- ? intl.formatMessage({
- id: "sign.list.message.wasm.button.close",
- })
- : intl.formatMessage({
- id: "sign.list.message.wasm.button.details",
- })}
-
-
- );
-});
-
-// eslint-disable-next-line @typescript-eslint/ban-types
-export const UnknownMsgView: FunctionComponent<{ msg: object }> = ({ msg }) => {
- const prettyMsg = useMemo(() => {
- try {
- return yaml.dump(msg);
- } catch (e) {
- console.log(e);
- return "Failed to decode the msg";
- }
- }, [msg]);
-
- return (
-
- );
-};
diff --git a/packages/fetch-extension/src/pages/sign/style.module.scss b/packages/fetch-extension/src/pages/sign/style.module.scss
deleted file mode 100644
index d73383a3fb..0000000000
--- a/packages/fetch-extension/src/pages/sign/style.module.scss
+++ /dev/null
@@ -1,67 +0,0 @@
-@import "../../styles/var";
-
-.tabs {
- ul {
- list-style: none;
- display: flex;
- flex: 1;
- padding: 0;
-
- li {
- flex: 1;
- text-align: center;
- border-bottom-color: #dbdbdb;
- border-bottom-style: solid;
- border-bottom-width: 1px;
- padding-bottom: 8px;
-
- &:global(.active) {
- border-bottom-color: #5e72e4;
- color: #5e72e4;
- }
- }
- }
-
- .tab {
- cursor: pointer;
- text-decoration: none;
- }
-}
-
-.buttons {
- display: flex;
- padding-top: 15px;
-}
-
-.button {
- flex: 1;
-}
-
-.container {
- flex: 1;
- display: flex;
- flex-direction: column;
-}
-
-.tabContainer {
- height: 342px;
- overflow: auto;
- display: flex;
- flex-direction: column;
-
- &.data-tab {
- overflow: auto;
- }
-}
-
-.message {
- margin-bottom: 0px;
- height: 400px;
- font-size: 12px;
- overflow: visible;
- background: transparent;
- word-wrap: break-word;
- white-space: pre-wrap;
- color: white;
- font-size: Lexend;
-}
diff --git a/packages/fetch-extension/src/pages/validator-list/index.tsx b/packages/fetch-extension/src/pages/validator-list/index.tsx
deleted file mode 100644
index 375b461ac8..0000000000
--- a/packages/fetch-extension/src/pages/validator-list/index.tsx
+++ /dev/null
@@ -1,179 +0,0 @@
-import searchIcon from "@assets/icon/search.png";
-import { Staking } from "@keplr-wallet/stores";
-import { CoinPretty } from "@keplr-wallet/unit";
-import { HeaderLayout } from "@layouts/header-layout";
-import { observer } from "mobx-react-lite";
-import React, { FunctionComponent, useEffect, useState } from "react";
-import { useLocation, useNavigate } from "react-router";
-import { useStore } from "../../stores";
-import { MyValidatorsList } from "./my-validators";
-import style from "./style.module.scss";
-import { ValidatorsList } from "./validators";
-
-type ValidatorData = Staking.Validator & { amount: CoinPretty };
-
-export enum ValidatorOperation {
- VALIDATOR = "validator",
- MY_STAKE = "myStake",
-}
-
-export const ValidatorList: FunctionComponent = observer(() => {
- const navigate = useNavigate();
- const location = useLocation();
- const operation = location.pathname.split("/")[2];
- const [validators, setValidators] = useState<{
- [key in string]: ValidatorData;
- }>({});
- const [filteredValidators, setFilteredValidators] = useState(
- []
- );
- const { analyticsStore } = useStore();
- const [loading, setLoading] = useState(true);
- const [searchInput, setSearchInput] = useState();
- const { chainStore, queriesStore, accountStore } = useStore();
- const queries = queriesStore.get(chainStore.current.chainId);
- const account = accountStore.getAccount(chainStore.current.chainId);
- const queryDelegations =
- queries.cosmos.queryDelegations.getQueryBech32Address(
- account.bech32Address
- );
- useEffect(() => {
- const fetchValidators = async () => {
- setLoading(true);
- const bondedValidators = await queries.cosmos.queryValidators
- .getQueryStatus(Staking.BondStatus.Bonded)
- .waitFreshResponse();
- const unbondingValidators = await queries.cosmos.queryValidators
- .getQueryStatus(Staking.BondStatus.Unbonding)
- .waitFreshResponse();
- const unbondedValidators = await queries.cosmos.queryValidators
- .getQueryStatus(Staking.BondStatus.Unbonded)
- .waitFreshResponse();
-
- const map: {
- [key in string]: ValidatorData;
- } = {};
- for (const val of [
- ...(bondedValidators?.data.validators || []),
- ...(unbondingValidators?.data.validators || []),
- ...(unbondedValidators?.data.validators || []),
- ]) {
- const amount = queryDelegations.getDelegationTo(val.operator_address);
-
- map[val.operator_address] = { ...val, amount };
- }
- setValidators(map);
- setFilteredValidators(Object.values(map));
- setLoading(false);
- };
- fetchValidators();
- }, [queries.cosmos.queryValidators, queryDelegations]);
-
- useEffect(() => {
- analyticsStore.logEvent(
- operation == ValidatorOperation.VALIDATOR
- ? "stake_validators_tab_click"
- : "stake_mystake_tab_click"
- );
- }, [operation]);
-
- const handleFilterValidators = (searchValue: string) => {
- const filteredValidators = Object.values(validators).filter((validator) =>
- searchValue?.trim().length
- ? validator.description.moniker
- ?.toLowerCase()
- .includes(searchValue.toLowerCase()) ||
- validator.operator_address
- ?.toLowerCase()
- .includes(searchValue.toLowerCase())
- : true
- );
- setFilteredValidators(filteredValidators);
- setSearchInput(searchValue);
- };
-
- return (
- {
- analyticsStore.logEvent("back_click", { pageName: "Stake" });
- navigate("/");
- }}
- >
-
-
{
- localStorage.setItem("validatorTab", ValidatorOperation.VALIDATOR);
- navigate(`/validators/${ValidatorOperation.VALIDATOR}`);
- analyticsStore.logEvent("stake_validators_tab_click");
- }}
- >
- Validators
-
-
-
{
- localStorage.setItem("validatorTab", ValidatorOperation.MY_STAKE);
- navigate(`/validators/${ValidatorOperation.MY_STAKE}`);
- }}
- >
- My Stake
-
-
-
-
-
-
handleFilterValidators(e.target.value)}
- />
-
-
- {loading && (
-
-
-
-
-
-
-
- Loading Validators
-
- )}
-
- {!loading && operation === ValidatorOperation.VALIDATOR && (
-
- )}
- {!loading && operation === ValidatorOperation.MY_STAKE && (
-
- )}
-
- );
-});
diff --git a/packages/fetch-extension/src/pages/validator-list/my-validator-card/index.tsx b/packages/fetch-extension/src/pages/validator-list/my-validator-card/index.tsx
deleted file mode 100644
index 1f70122327..0000000000
--- a/packages/fetch-extension/src/pages/validator-list/my-validator-card/index.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import { ToolTip } from "@components/tooltip";
-import { Staking } from "@keplr-wallet/stores";
-import { CoinPretty } from "@keplr-wallet/unit";
-import { formatAddress, shortenMintingNumber } from "@utils/format";
-import React from "react";
-import { useNavigate } from "react-router";
-import { CHAIN_ID_DORADO, CHAIN_ID_FETCHHUB } from "../../../config.ui.var";
-import styleValidators from "./validators.module.scss";
-import { useStore } from "../../../stores";
-
-export const URL: { [key in string]: string } = {
- [CHAIN_ID_DORADO]: "https://explore-dorado.fetch.ai/validators",
- [CHAIN_ID_FETCHHUB]: "https://www.mintscan.io/fetchai/validators",
-};
-
-export const MyValidatorCard = ({
- validator,
- chainID,
-}: {
- validator: Staking.Validator & { amount: CoinPretty };
- chainID: string;
-}) => {
- const navigate = useNavigate();
- const { analyticsStore } = useStore();
- const status = validator.status.split("_")[2].toLowerCase();
- const commisionRate = (
- parseFloat(validator.commission.commission_rates.rate) * 100
- ).toFixed(2);
- return (
- {
- analyticsStore.logEvent("stake_validator_click", {
- pageName: "My Stake Tab",
- });
- navigate(`/validators/${validator.operator_address}/stake`);
- }}
- >
-
-
- {validator.description.moniker}
-
-
- {validator.operator_address}
-
- }
- >
-
- {formatAddress(validator.operator_address)}
-
-
-
-
-
- Staked
-
- {shortenMintingNumber(validator.amount.toDec().toString(), 0)}
- {validator.amount.currency.coinDenom}
-
-
-
- Commission
- {commisionRate}%
-
-
- Status
- {status}
-
-
-
- View in Explorer
-
-
- );
-};
diff --git a/packages/fetch-extension/src/pages/validator-list/my-validator-card/validators.module.scss b/packages/fetch-extension/src/pages/validator-list/my-validator-card/validators.module.scss
deleted file mode 100644
index d848d5ee07..0000000000
--- a/packages/fetch-extension/src/pages/validator-list/my-validator-card/validators.module.scss
+++ /dev/null
@@ -1,57 +0,0 @@
-.col {
- text-align: center;
- display: flex;
- flex-direction: column;
- gap: 4px;
- font-size: 12px;
- text-transform: capitalize;
-}
-
-.row {
- display: flex;
- justify-content: space-between;
- width: 100%;
-}
-
-.label {
- font-weight: bold;
- text-transform: capitalize;
-}
-
-.address {
- font-style: italic;
- font-size: 12px;
-}
-
-.avatar {
- width: 80px;
- height: 80px;
- line-height: initial;
- text-align: center;
- color: rgb(255, 255, 255);
- border-radius: 100%;
- background: rgb(214, 26, 127);
-}
-.item {
- display: flex;
- flex-direction: column;
- gap: 8px;
- width: 100%;
- padding: 10px;
- background: #ffffff;
- border-radius: 6px;
- cursor: pointer;
- margin: 10px 0px;
-}
-
-.item:hover {
- box-shadow: 0 0 100px 30px #e0e0e0 inset;
-}
-
-.tooltip {
- font-weight: 400;
- font-size: 10px;
- line-height: 10px;
-
- padding: 2px 4px;
-}
diff --git a/packages/fetch-extension/src/pages/validator-list/my-validators/index.tsx b/packages/fetch-extension/src/pages/validator-list/my-validators/index.tsx
deleted file mode 100644
index 362f33ba8d..0000000000
--- a/packages/fetch-extension/src/pages/validator-list/my-validators/index.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Staking } from "@keplr-wallet/stores";
-import { CoinPretty } from "@keplr-wallet/unit";
-import React from "react";
-import { useStore } from "../../../stores";
-import { MyValidatorCard } from "../my-validator-card";
-
-type ValidatorData = Staking.Validator & { amount: CoinPretty };
-
-export const MyValidatorsList = ({
- filteredValidators,
-}: {
- filteredValidators: ValidatorData[];
-}) => {
- const { chainStore } = useStore();
-
- const filterValidators = (validator: ValidatorData) => {
- return validator.amount
- .toDec()
- .gt(new CoinPretty(validator.amount.currency, "0").toDec());
- };
-
- const sortValidators = (a: ValidatorData, b: ValidatorData) => {
- return (
- parseFloat(b.amount.toDec().toString()) -
- parseFloat(a.amount.toDec().toString())
- );
- };
-
- return (
-
- {filteredValidators.length ? (
- filteredValidators
- .filter(filterValidators)
- .sort(sortValidators)
- .map((validator: ValidatorData) => (
-
- ))
- ) : (
- No Validators Found
- )}
-
- );
-};
diff --git a/packages/fetch-extension/src/pages/validator-list/style.module.scss b/packages/fetch-extension/src/pages/validator-list/style.module.scss
deleted file mode 100644
index a6a464b2bf..0000000000
--- a/packages/fetch-extension/src/pages/validator-list/style.module.scss
+++ /dev/null
@@ -1,129 +0,0 @@
-.searchContainer {
- margin: 12px 0px;
- display: flex;
- align-items: center;
- .searchBox {
- display: flex;
- padding: 5px;
- flex: 1;
- background-color: #f2f3f6;
- border-radius: 4px;
- align-items: center;
- gap: 10px;
- img {
- width: 16px;
- height: 16px;
- -webkit-user-drag: none;
- -khtml-user-drag: none;
- -moz-user-drag: none;
- -o-user-drag: none;
- }
- input {
- border: none;
- outline: none;
- background: transparent;
- &::placeholder {
- color: #525f7f;
- }
- flex-grow: 1;
- }
- }
-}
-
-.loader {
- display: inline-block;
- margin: 0 16px;
-}
-
-.loader {
- --path: #2f3545;
- --dot: #5628ee;
- --duration: 2s;
- width: 44px;
- height: 44px;
- position: relative;
-}
-
-.loader:before {
- content: "";
- width: 6px;
- height: 6px;
- border-radius: 50%;
- position: absolute;
- display: block;
- background: var(--dot);
- top: 37px;
- left: 19px;
- transform: translate(-18px, -18px);
- animation: dotRect var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86)
- infinite;
-}
-
-.loader svg {
- display: block;
- width: 100%;
- height: 100%;
-}
-
-.loader svg rect,
-.loader svg polygon,
-.loader svg circle {
- fill: none;
- stroke: var(--path);
- stroke-width: 10px;
- stroke-linejoin: round;
- stroke-linecap: round;
-}
-
-.loader svg rect {
- stroke-dasharray: 192 64 192 64;
- stroke-dashoffset: 0;
- animation: pathRect 2s cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
-}
-
-.tabList {
- display: flex;
- flex-direction: row;
-}
-
-.tab {
- width: 50%;
- text-align: center;
- cursor: pointer;
-}
-
-@keyframes pathRect {
- 25% {
- stroke-dashoffset: 64;
- }
-
- 50% {
- stroke-dashoffset: 128;
- }
-
- 75% {
- stroke-dashoffset: 192;
- }
-
- 100% {
- stroke-dashoffset: 256;
- }
-}
-
-@keyframes dotRect {
- 25% {
- transform: translate(0, 0);
- }
-
- 50% {
- transform: translate(18px, -18px);
- }
-
- 75% {
- transform: translate(0, -36px);
- }
-
- 100% {
- transform: translate(-18px, -18px);
- }
-}
diff --git a/packages/fetch-extension/src/pages/validator-list/validator-card/validators.module.scss b/packages/fetch-extension/src/pages/validator-list/validator-card/validators.module.scss
deleted file mode 100644
index d848d5ee07..0000000000
--- a/packages/fetch-extension/src/pages/validator-list/validator-card/validators.module.scss
+++ /dev/null
@@ -1,57 +0,0 @@
-.col {
- text-align: center;
- display: flex;
- flex-direction: column;
- gap: 4px;
- font-size: 12px;
- text-transform: capitalize;
-}
-
-.row {
- display: flex;
- justify-content: space-between;
- width: 100%;
-}
-
-.label {
- font-weight: bold;
- text-transform: capitalize;
-}
-
-.address {
- font-style: italic;
- font-size: 12px;
-}
-
-.avatar {
- width: 80px;
- height: 80px;
- line-height: initial;
- text-align: center;
- color: rgb(255, 255, 255);
- border-radius: 100%;
- background: rgb(214, 26, 127);
-}
-.item {
- display: flex;
- flex-direction: column;
- gap: 8px;
- width: 100%;
- padding: 10px;
- background: #ffffff;
- border-radius: 6px;
- cursor: pointer;
- margin: 10px 0px;
-}
-
-.item:hover {
- box-shadow: 0 0 100px 30px #e0e0e0 inset;
-}
-
-.tooltip {
- font-weight: 400;
- font-size: 10px;
- line-height: 10px;
-
- padding: 2px 4px;
-}
diff --git a/packages/fetch-extension/src/pages/validator-list/validators/index.tsx b/packages/fetch-extension/src/pages/validator-list/validators/index.tsx
deleted file mode 100644
index 1b2832ea58..0000000000
--- a/packages/fetch-extension/src/pages/validator-list/validators/index.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Staking } from "@keplr-wallet/stores";
-import { CoinPretty } from "@keplr-wallet/unit";
-import React from "react";
-import { useStore } from "../../../stores";
-import { ValidatorCard } from "../validator-card";
-
-type ValidatorData = Staking.Validator & { amount: CoinPretty };
-
-export const ValidatorsList = ({
- filteredValidators,
-}: {
- filteredValidators: ValidatorData[];
-}) => {
- const { chainStore } = useStore();
-
- const sortValidators = (a: ValidatorData, b: ValidatorData) => {
- return parseFloat(b.delegator_shares) - parseFloat(a.delegator_shares);
- };
-
- return (
-
- {filteredValidators.length ? (
- filteredValidators
- .sort((a, b) => sortValidators(a, b))
- .map((validator: ValidatorData) => (
-
- ))
- ) : (
- No Validators Found
- )}
-
- );
-};
diff --git a/packages/fetch-extension/src/pages/validator/index.tsx b/packages/fetch-extension/src/pages/validator/index.tsx
deleted file mode 100644
index 9c0dbc3427..0000000000
--- a/packages/fetch-extension/src/pages/validator/index.tsx
+++ /dev/null
@@ -1,185 +0,0 @@
-import { Staking } from "@keplr-wallet/stores";
-import { HeaderLayout } from "@layouts/header-layout";
-import { observer } from "mobx-react-lite";
-import React, { FunctionComponent, useMemo } from "react";
-import { useLocation, useNavigate } from "react-router";
-import { useStore } from "../../stores";
-import { Stake } from "./stake";
-import style from "./style.module.scss";
-import { Transfer } from "./transfer";
-import { Unstake } from "./unstake";
-import { ValidatorDetails } from "./validator-details";
-import { Dec } from "@keplr-wallet/unit";
-
-enum ValidatorOperation {
- STAKE = "stake",
- UNSTAKE = "unstake",
- TRANSFER = "transfer",
-}
-
-export const Validator: FunctionComponent = observer(() => {
- const navigate = useNavigate();
- const location = useLocation();
- const validatorAddress = location.pathname.split("/")[2];
- const operation = location.pathname.split("/")[3];
- const validatorTab = localStorage.getItem("validatorTab") || "validator";
- const { chainStore, accountStore, queriesStore, analyticsStore } = useStore();
- const account = accountStore.getAccount(chainStore.current.chainId);
- const queries = queriesStore.get(chainStore.current.chainId);
-
- const bondedValidators = queries.cosmos.queryValidators.getQueryStatus(
- Staking.BondStatus.Bonded
- );
- const unbondingValidators = queries.cosmos.queryValidators.getQueryStatus(
- Staking.BondStatus.Unbonding
- );
- const unbondedValidators = queries.cosmos.queryValidators.getQueryStatus(
- Staking.BondStatus.Unbonded
- );
- const queryDelegations =
- queries.cosmos.queryDelegations.getQueryBech32Address(
- account.bech32Address
- );
- const queryRewards = queries.cosmos.queryRewards.getQueryBech32Address(
- account.bech32Address
- );
- const { validator, amount, rewards } = useMemo(() => {
- const amount = queryDelegations.getDelegationTo(validatorAddress);
- const validator =
- bondedValidators.getValidator(validatorAddress) ||
- unbondingValidators.getValidator(validatorAddress) ||
- unbondedValidators.getValidator(validatorAddress);
- const thumbnail =
- bondedValidators.getValidatorThumbnail(validatorAddress) ||
- unbondingValidators.getValidatorThumbnail(validatorAddress) ||
- unbondedValidators.getValidatorThumbnail(validatorAddress);
- const rewards = queryRewards.getRewardsOf(validatorAddress);
- return {
- validator,
- thumbnail,
- rewards,
- amount: amount,
- };
- }, [
- queryDelegations,
- validatorAddress,
- bondedValidators,
- unbondingValidators,
- unbondedValidators,
- queryRewards,
- ]);
- const inflation = queries.cosmos.queryInflation;
- const { inflation: ARR, isFetching } = inflation;
- const validatorCom: any = parseFloat(
- validator?.commission.commission_rates.rate || "0"
- );
- const APR = ARR.mul(new Dec(1 - validatorCom));
- return (
- {
- analyticsStore.logEvent("back_click", { pageName: "Validator Detail" });
- navigate(`/validators/${validatorTab}`);
- }}
- >
-
- {validator && (
-
- )}
-
-
-
Current Staked Amount
-
- {amount.maxDecimals(4).trim(true).toString()}
-
-
-
-
navigate(`/validators/${validatorAddress}/stake`)}
- >
- Stake
-
-
-
- navigate(`/validators/${validatorAddress}/unstake`)
- }
- >
- Unstake
-
-
- navigate(`/validators/${validatorAddress}/transfer`)
- }
- >
- Redelegate
-
-
- {operation == ValidatorOperation.STAKE && (
-
- )}
- {operation == ValidatorOperation.UNSTAKE && (
-
- )}
- {operation == ValidatorOperation.TRANSFER && (
-
validator.operator_address != validatorAddress
- )}
- />
- )}
-
-
-
- );
-});
diff --git a/packages/fetch-extension/src/pages/validator/stake-complete.tsx b/packages/fetch-extension/src/pages/validator/stake-complete.tsx
deleted file mode 100644
index b2b986d59c..0000000000
--- a/packages/fetch-extension/src/pages/validator/stake-complete.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import { HeaderLayout } from "@layouts/header-layout";
-import React, { FunctionComponent, useMemo } from "react";
-import { useLocation, useNavigate } from "react-router";
-import { Button } from "reactstrap";
-import activeStake from "@assets/icon/activeStake.png";
-import { Staking } from "@keplr-wallet/stores";
-import { useStore } from "../../stores";
-import { observer } from "mobx-react-lite";
-
-export const StakeComplete: FunctionComponent = observer(() => {
- const navigate = useNavigate();
- const validatorAddress = useLocation().pathname.split("/")[2];
- const validatorTab = localStorage.getItem("validatorTab");
- const { chainStore, queriesStore } = useStore();
- const queries = queriesStore.get(chainStore.current.chainId);
-
- const bondedValidators = queries.cosmos.queryValidators.getQueryStatus(
- Staking.BondStatus.Bonded
- );
- const unbondingValidators = queries.cosmos.queryValidators.getQueryStatus(
- Staking.BondStatus.Unbonding
- );
- const unbondedValidators = queries.cosmos.queryValidators.getQueryStatus(
- Staking.BondStatus.Unbonded
- );
-
- const { validator } = useMemo(() => {
- const validator =
- bondedValidators.getValidator(validatorAddress) ||
- unbondingValidators.getValidator(validatorAddress) ||
- unbondedValidators.getValidator(validatorAddress);
- return {
- validator,
- };
- }, [
- bondedValidators,
- validatorAddress,
- unbondingValidators,
- unbondedValidators,
- ]);
-
- return (
-
-
-
- {validator && (
-
- Amount processed with
-
- {validator.description.moniker}
-
-
- )}
-
-
- navigate("/")}>
- Return Home
-
-
- navigate(`/validators/${validatorTab}`)}
- style={{ marginLeft: "0px" }}
- >
-
- Go back to Validators List
-
-
- );
-});
diff --git a/packages/fetch-extension/src/pages/validator/stake.tsx b/packages/fetch-extension/src/pages/validator/stake.tsx
deleted file mode 100644
index 8277cd90a6..0000000000
--- a/packages/fetch-extension/src/pages/validator/stake.tsx
+++ /dev/null
@@ -1,202 +0,0 @@
-import activeStake from "@assets/icon/activeStake.png";
-import { useNotification } from "@components/notification";
-import {
- EmptyAmountError,
- InsufficientAmountError,
- InvalidNumberAmountError,
- NegativeAmountError,
- ZeroAmountError,
- useDelegateTxConfig,
-} from "@keplr-wallet/hooks";
-import { CoinPretty, Int } from "@keplr-wallet/unit";
-import { observer } from "mobx-react-lite";
-import React, { FunctionComponent, useMemo } from "react";
-import { useIntl } from "react-intl";
-import { useNavigate } from "react-router";
-import { Button, FormGroup, Input, Label } from "reactstrap";
-import { useStore } from "../../stores";
-import style from "./style.module.scss";
-import { TXNTYPE } from "../../config";
-
-export const Stake: FunctionComponent<{ validatorAddress: string }> = observer(
- ({ validatorAddress }) => {
- const navigate = useNavigate();
- const { chainStore, accountStore, queriesStore, analyticsStore } =
- useStore();
- const account = accountStore.getAccount(chainStore.current.chainId);
-
- const sendConfigs = useDelegateTxConfig(
- chainStore,
- queriesStore,
- accountStore,
- chainStore.current.chainId,
- account.bech32Address
- );
- const { amountConfig, memoConfig, feeConfig } = sendConfigs;
-
- const intl = useIntl();
- const error = amountConfig.error;
-
- const queryBalances = queriesStore
- .get(amountConfig.chainId)
- .queryBalances.getQueryBech32Address(amountConfig.sender);
-
- const queryBalance = queryBalances.balances.find(
- (bal) =>
- amountConfig.sendCurrency.coinMinimalDenom ===
- bal.currency.coinMinimalDenom
- );
- const balance = queryBalance
- ? queryBalance.balance
- : new CoinPretty(amountConfig.sendCurrency, new Int(0));
-
- const errorText: string | undefined = useMemo(() => {
- if (error) {
- switch (error.constructor) {
- case EmptyAmountError:
- // No need to show the error to user.
- return;
- case InvalidNumberAmountError:
- return intl.formatMessage({
- id: "input.amount.error.invalid-number",
- });
- case ZeroAmountError:
- return intl.formatMessage({
- id: "input.amount.error.is-zero",
- });
- case NegativeAmountError:
- return intl.formatMessage({
- id: "input.amount.error.is-negative",
- });
- case InsufficientAmountError:
- return intl.formatMessage({
- id: "input.amount.error.insufficient",
- });
- default:
- return intl.formatMessage({ id: "input.amount.error.unknown" });
- }
- }
- }, [intl, error]);
-
- const notification = useNotification();
-
- const txnResult = {
- onBroadcasted: () => {
- notification.push({
- type: "primary",
- placement: "top-center",
- duration: 2,
- content: `Transaction broadcasted`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- analyticsStore.logEvent("stake_txn_broadcasted", {
- chainId: chainStore.current.chainId,
- chainName: chainStore.current.chainName,
- feeType: feeConfig.feeType,
- });
- },
- onFulfill: (tx: any) => {
- const istxnSuccess = tx.code ? false : true;
- notification.push({
- type: istxnSuccess ? "success" : "danger",
- placement: "top-center",
- duration: 5,
- content: istxnSuccess
- ? `Transaction Completed`
- : `Transaction Failed: ${tx.log}`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- },
- };
- const stakeClicked = async () => {
- try {
- analyticsStore.logEvent("stake_txn_click");
- await account.cosmos
- .makeDelegateTx(amountConfig.amount, validatorAddress)
- .send(feeConfig.toStdFee(), memoConfig.memo, undefined, txnResult);
- } catch (e) {
- notification.push({
- type: "danger",
- placement: "top-center",
- duration: 5,
- content: `Transaction Failed`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- analyticsStore.logEvent("stake_txn_broadcasted_fail", {
- chainId: chainStore.current.chainId,
- chainName: chainStore.current.chainName,
- feeType: feeConfig.feeType,
- message: e?.message ?? "",
- });
- } finally {
- navigate("/", { replace: true });
- }
- };
-
- return (
-
-
-
- {
- e.preventDefault();
- amountConfig.toggleIsMax();
- }}
- >{`Balance: ${balance.trim(true).maxDecimals(6).toString()}`}
-
- {
- e.preventDefault();
- amountConfig.setAmount(e.target.value);
- }}
- style={{ borderRadius: "0%" }}
- min={0}
- autoComplete="off"
- />
- {errorText != null ? (
- {errorText}
- ) : null}
-
-
- Stake
- {account.txTypeInProgress === TXNTYPE.delegate && (
-
- )}
-
-
-
- );
- }
-);
diff --git a/packages/fetch-extension/src/pages/validator/style.module.scss b/packages/fetch-extension/src/pages/validator/style.module.scss
deleted file mode 100644
index 19bfb491f4..0000000000
--- a/packages/fetch-extension/src/pages/validator/style.module.scss
+++ /dev/null
@@ -1,153 +0,0 @@
-.stakeContainer {
- display: flex;
- justify-content: space-between;
- flex-direction: column;
- height: 100%;
-}
-
-.stakedAmount {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 5px;
- font-size: 14px;
-}
-
-.tabList {
- display: flex;
- flex-direction: row;
-}
-
-.tab {
- width: 50%;
- text-align: center;
- cursor: pointer;
-}
-
-.stakeValueInput {
- padding: 8px;
- border: none;
- margin-bottom: 10px;
-}
-
-.nextStakedValidatorName {
- text-align: center;
- color: #5090ff;
- margin-bottom: 10px;
-}
-
-.nextStakedInfo {
- text-align: center;
-}
-
-.balance {
- text-align: right;
- font-weight: normal;
- color: #555555;
- cursor: pointer;
-
- &:hover {
- color: black;
- text-decoration: underline;
- }
-
- &.clicked {
- color: black;
- }
-}
-
-.errorText {
- color: #fb8c72;
- font: 10px;
-}
-
-.loader {
- display: inline-block;
- margin: 0 16px;
-}
-
-.loader {
- --path: #2f3545;
- --dot: #5628ee;
- --duration: 2s;
- width: 44px;
- height: 44px;
- position: relative;
-}
-
-.loader:before {
- content: "";
- width: 6px;
- height: 6px;
- border-radius: 50%;
- position: absolute;
- display: block;
- background: var(--dot);
- top: 37px;
- left: 19px;
- transform: translate(-18px, -18px);
- animation: dotRect var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86)
- infinite;
-}
-
-.loader svg {
- display: block;
- width: 100%;
- height: 100%;
-}
-
-.loader svg rect,
-.loader svg polygon,
-.loader svg circle {
- fill: none;
- stroke: var(--path);
- stroke-width: 10px;
- stroke-linejoin: round;
- stroke-linecap: round;
-}
-
-.loader svg rect {
- stroke-dasharray: 192 64 192 64;
- stroke-dashoffset: 0;
- animation: pathRect 2s cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
-}
-
-.dropdown:hover {
- background: aliceblue !important;
-}
-
-@keyframes pathRect {
- 25% {
- stroke-dashoffset: 64;
- }
-
- 50% {
- stroke-dashoffset: 128;
- }
-
- 75% {
- stroke-dashoffset: 192;
- }
-
- 100% {
- stroke-dashoffset: 256;
- }
-}
-
-@keyframes dotRect {
- 25% {
- transform: translate(0, 0);
- }
-
- 50% {
- transform: translate(18px, -18px);
- }
-
- 75% {
- transform: translate(0, -36px);
- }
-
- 100% {
- transform: translate(-18px, -18px);
- }
-}
diff --git a/packages/fetch-extension/src/pages/validator/transfer.tsx b/packages/fetch-extension/src/pages/validator/transfer.tsx
deleted file mode 100644
index 4b178eda09..0000000000
--- a/packages/fetch-extension/src/pages/validator/transfer.tsx
+++ /dev/null
@@ -1,259 +0,0 @@
-import activeStake from "@assets/icon/activeStake.png";
-import { useNotification } from "@components/notification";
-import {
- EmptyAmountError,
- InsufficientAmountError,
- InvalidNumberAmountError,
- NegativeAmountError,
- ZeroAmountError,
- useRedelegateTxConfig,
-} from "@keplr-wallet/hooks";
-import { observer } from "mobx-react-lite";
-import React, { FunctionComponent, useMemo, useState } from "react";
-import { useIntl } from "react-intl";
-import { useNavigate } from "react-router";
-import {
- Button,
- ButtonDropdown,
- DropdownItem,
- DropdownMenu,
- DropdownToggle,
- FormGroup,
- Input,
- Label,
-} from "reactstrap";
-import { useStore } from "../../stores";
-import style from "./style.module.scss";
-import { Staking } from "@keplr-wallet/stores";
-import { CoinPretty } from "@keplr-wallet/unit";
-import { TXNTYPE } from "../../config";
-
-export const Transfer: FunctionComponent<{
- validatorAddress: string;
- validatorsList: Staking.Validator[];
- balance: CoinPretty;
-}> = observer(({ validatorAddress, validatorsList, balance }) => {
- const navigate = useNavigate();
- const { chainStore, accountStore, queriesStore, analyticsStore } = useStore();
- const account = accountStore.getAccount(chainStore.current.chainId);
- const [selectedValidator, setSelectedValidator] = useState(
- validatorsList[0]
- );
- const [showDropdown, setShowDropdown] = useState(false);
- const sendConfigs = useRedelegateTxConfig(
- chainStore,
- queriesStore,
- accountStore,
- chainStore.current.chainId,
- account.bech32Address,
- validatorAddress
- );
- const { amountConfig, memoConfig, feeConfig } = sendConfigs;
-
- const intl = useIntl();
- const error = amountConfig.error;
-
- const errorText: string | undefined = useMemo(() => {
- if (error) {
- switch (error.constructor) {
- case EmptyAmountError:
- // No need to show the error to user.
- return;
- case InvalidNumberAmountError:
- return intl.formatMessage({
- id: "input.amount.error.invalid-number",
- });
- case ZeroAmountError:
- return intl.formatMessage({
- id: "input.amount.error.is-zero",
- });
- case NegativeAmountError:
- return intl.formatMessage({
- id: "input.amount.error.is-negative",
- });
- case InsufficientAmountError:
- return intl.formatMessage({
- id: "input.amount.error.insufficient",
- });
- default:
- return intl.formatMessage({ id: "input.amount.error.unknown" });
- }
- }
- }, [intl, error]);
-
- const notification = useNotification();
-
- const txnResult = {
- onBroadcasted: () => {
- notification.push({
- type: "primary",
- placement: "top-center",
- duration: 2,
- content: `Transaction broadcasted`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- analyticsStore.logEvent("redelegate_txn_broadcasted", {
- chainId: chainStore.current.chainId,
- chainName: chainStore.current.chainName,
- feeType: feeConfig.feeType,
- });
- },
- onFulfill: (tx: any) => {
- const istxnSuccess = tx.code ? false : true;
- notification.push({
- type: istxnSuccess ? "success" : "danger",
- placement: "top-center",
- duration: 5,
- content: istxnSuccess
- ? `Transaction Completed`
- : `Transaction Failed: ${tx.log}`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- },
- };
- const stakeClicked = async () => {
- try {
- analyticsStore.logEvent("redelegate_txn_click");
- await account.cosmos
- .makeBeginRedelegateTx(
- amountConfig.amount,
- validatorAddress,
- selectedValidator.operator_address
- )
- .send(feeConfig.toStdFee(), memoConfig.memo, undefined, txnResult);
- } catch (e) {
- notification.push({
- type: "danger",
- placement: "top-center",
- duration: 5,
- content: `Transaction Failed`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- analyticsStore.logEvent("redelegate_txn_broadcasted_fail", {
- chainId: chainStore.current.chainId,
- chainName: chainStore.current.chainName,
- feeType: feeConfig.feeType,
- message: e?.message ?? "",
- });
- } finally {
- navigate("/", { replace: true });
- }
- };
-
- return (
-
-
-
- Select Validator
-
- setShowDropdown((value) => !value)}
- style={{ float: "right" }}
- >
-
-
- {selectedValidator.description.moniker}
-
-
-
-
-
- {validatorsList.map((validator) => {
- return (
- {
- analyticsStore.logEvent("stake_validator_click", {
- pageName: "Validator Detail Page",
- });
- setSelectedValidator(validator);
- }}
- >
- {validator.description.moniker}
-
- );
- })}
-
-
-
-
- {
- e.preventDefault();
-
- amountConfig.toggleIsMax();
- }}
- >{`Staked: ${balance.trim(true).maxDecimals(6).toString()}`}
-
- {
- e.preventDefault();
- amountConfig.setAmount(e.target.value);
- }}
- style={{ borderRadius: "0%" }}
- min={0}
- autoComplete="off"
- />
- {errorText != null ? (
- {errorText}
- ) : null}
-
-
-
- Redelegate
- {account.txTypeInProgress === TXNTYPE.redelegate && (
-
- )}
-
-
-
- );
-});
diff --git a/packages/fetch-extension/src/pages/validator/unstake.tsx b/packages/fetch-extension/src/pages/validator/unstake.tsx
deleted file mode 100644
index 63c57ffa81..0000000000
--- a/packages/fetch-extension/src/pages/validator/unstake.tsx
+++ /dev/null
@@ -1,199 +0,0 @@
-import activeStake from "@assets/icon/activeStake.png";
-import { useNotification } from "@components/notification";
-import {
- EmptyAmountError,
- InsufficientAmountError,
- InvalidNumberAmountError,
- NegativeAmountError,
- ZeroAmountError,
- useUndelegateTxConfig,
-} from "@keplr-wallet/hooks";
-import { observer } from "mobx-react-lite";
-import React, { FunctionComponent, useMemo } from "react";
-import { useIntl } from "react-intl";
-import { useNavigate } from "react-router";
-import { Button, FormGroup, Input, Label } from "reactstrap";
-import { useStore } from "../../stores";
-import style from "./style.module.scss";
-import { TXNTYPE } from "../../config";
-
-export const Unstake: FunctionComponent<{
- validatorAddress: string;
-}> = observer(({ validatorAddress }) => {
- const navigate = useNavigate();
- const { chainStore, accountStore, queriesStore, analyticsStore } = useStore();
- const account = accountStore.getAccount(chainStore.current.chainId);
-
- const sendConfigs = useUndelegateTxConfig(
- chainStore,
- queriesStore,
- accountStore,
- chainStore.current.chainId,
- account.bech32Address,
- validatorAddress
- );
- const { amountConfig, memoConfig, feeConfig } = sendConfigs;
-
- const intl = useIntl();
- const error = amountConfig.error;
-
- const balance = queriesStore
- .get(amountConfig.chainId)
- .cosmos.queryDelegations.getQueryBech32Address(amountConfig.sender)
- .getDelegationTo(validatorAddress);
-
- const errorText: string | undefined = useMemo(() => {
- if (error) {
- switch (error.constructor) {
- case EmptyAmountError:
- // No need to show the error to user.
- return;
- case InvalidNumberAmountError:
- return intl.formatMessage({
- id: "input.amount.error.invalid-number",
- });
- case ZeroAmountError:
- return intl.formatMessage({
- id: "input.amount.error.is-zero",
- });
- case NegativeAmountError:
- return intl.formatMessage({
- id: "input.amount.error.is-negative",
- });
- case InsufficientAmountError:
- return intl.formatMessage({
- id: "input.amount.error.insufficient",
- });
- default:
- return intl.formatMessage({ id: "input.amount.error.unknown" });
- }
- }
- }, [intl, error]);
-
- const notification = useNotification();
-
- const txnResult = {
- onBroadcasted: () => {
- notification.push({
- type: "primary",
- placement: "top-center",
- duration: 2,
- content: `Transaction broadcasted`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
-
- analyticsStore.logEvent("unstake_txn_broadcasted", {
- chainId: chainStore.current.chainId,
- chainName: chainStore.current.chainName,
- feeType: feeConfig.feeType,
- });
- },
- onFulfill: (tx: any) => {
- const istxnSuccess = tx.code ? false : true;
- notification.push({
- type: istxnSuccess ? "success" : "danger",
- placement: "top-center",
- duration: 5,
- content: istxnSuccess
- ? `Transaction Completed`
- : `Transaction Failed: ${tx.log}`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- },
- };
-
- const stakeClicked = async () => {
- try {
- analyticsStore.logEvent("unstake_txn_click");
- await account.cosmos
- .makeUndelegateTx(amountConfig.amount, validatorAddress)
- .send(feeConfig.toStdFee(), memoConfig.memo, undefined, txnResult);
- } catch (e) {
- analyticsStore.logEvent("unstake_txn_broadcasted_fail", {
- chainId: chainStore.current.chainId,
- chainName: chainStore.current.chainName,
- feeType: feeConfig.feeType,
- message: e?.message ?? "",
- });
- notification.push({
- type: "danger",
- placement: "top-center",
- duration: 5,
- content: `Transaction Failed`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- } finally {
- navigate("/", { replace: true });
- }
- };
-
- return (
-
-
-
- {
- e.preventDefault();
-
- amountConfig.toggleIsMax();
- }}
- >{`Staked: ${balance.trim(true).maxDecimals(6).toString()}`}
-
- {
- e.preventDefault();
- amountConfig.setAmount(e.target.value);
- }}
- style={{ borderRadius: "0%" }}
- min={0}
- autoComplete="off"
- />
- {errorText != null ? (
- {errorText}
- ) : null}
-
- Your tokens will go through a 21-day unstaking process
-
-
-
- Unstake
- {account.txTypeInProgress === TXNTYPE.undelegate && (
-
- )}
-
-
-
- );
-});
diff --git a/packages/fetch-extension/src/pages/validator/validator-details/index.tsx b/packages/fetch-extension/src/pages/validator/validator-details/index.tsx
deleted file mode 100644
index 077928c9f9..0000000000
--- a/packages/fetch-extension/src/pages/validator/validator-details/index.tsx
+++ /dev/null
@@ -1,219 +0,0 @@
-import { ToolTip } from "@components/tooltip";
-import { Staking } from "@keplr-wallet/stores";
-import { formatAddress, shortenNumber } from "@utils/format";
-import React from "react";
-import { useStore } from "../../../stores";
-import { CHAIN_ID_DORADO, CHAIN_ID_FETCHHUB } from "../../../config.ui.var";
-import styleValidators from "./validatordetails.module.scss";
-import { useNavigate } from "react-router";
-import { useNotification } from "@components/notification";
-
-export const URL: { [key in string]: string } = {
- [CHAIN_ID_DORADO]: "https://explore-dorado.fetch.ai/validators",
- [CHAIN_ID_FETCHHUB]: "https://www.mintscan.io/fetchai/validators",
-};
-
-export const ValidatorDetails = ({
- validator,
- chainID,
- rewards,
- APR,
- isFetching,
-}: {
- validator: Staking.Validator;
- chainID: string;
- rewards: any;
- APR: any;
- isFetching: boolean;
-}) => {
- const { chainStore, accountStore } = useStore();
- const account = accountStore.getAccount(chainStore.current.chainId);
- const navigate = useNavigate();
- const notification = useNotification();
- const { analyticsStore } = useStore();
- const status = validator.status.split("_")[2].toLowerCase();
-
- const commisionRate = (
- parseFloat(validator.commission.commission_rates.rate) * 100
- ).toFixed(2);
- const maxCommisionRate = (
- parseFloat(validator.commission.commission_rates.max_rate) * 100
- ).toFixed(2);
-
- const handleClaim = async () => {
- try {
- analyticsStore.logEvent("claim_click", {
- pageName: "Validator Detail",
- });
- await account.cosmos.sendWithdrawDelegationRewardMsgs(
- [validator.operator_address],
- "",
- undefined,
- undefined,
- {
- onBroadcasted() {
- notification.push({
- type: "primary",
- placement: "top-center",
- duration: 5,
- content: `Transaction Broadcasted`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- analyticsStore.logEvent("claim_txn_broadcasted", {
- chainId: chainStore.current.chainId,
- chainName: chainStore.current.chainName,
- });
- },
- onFulfill: (tx: any) => {
- const istxnSuccess = tx.code ? false : true;
- notification.push({
- type: istxnSuccess ? "success" : "danger",
- placement: "top-center",
- duration: 5,
- content: istxnSuccess
- ? `Transaction Completed`
- : `Transaction Failed`,
- canDelete: true,
- transition: {
- duration: 0.25,
- },
- });
- },
- }
- );
- navigate(`/validators/${validator.operator_address}/stake`);
- } catch (err) {
- console.error(err);
- if (err.toString().includes("Error: Request rejected")) {
- navigate(`/validators/${validator.operator_address}/stake`);
- }
- analyticsStore.logEvent("claim_txn_broadcasted_fail", {
- chainId: chainStore.current.chainId,
- chainName: chainStore.current.chainName,
- message: err?.message ?? "",
- });
- }
- };
- return (
-
-
-
-
- {validator.operator_address}
-
- }
- >
-
- {formatAddress(validator.operator_address)}
-
-
-
- {validator.description.details && (
-
- Description
- {validator.description.details}
-
- )}
-
-
- Commission Rate
-
- {commisionRate}% ({maxCommisionRate}% Max)
-
-
-
- Delegated
- {shortenNumber(validator.delegator_shares)}
-
-
- Status
- {status}
-
-
-
-
-
-
APR
-
- {!isFetching ? (
- {APR.maxDecimals(2).trim(true).toString()}%
- ) : (
-
-
-
- )}
-
-
-
-
Earned Rewards
-
- {!isFetching ? (
-
- {!rewards ||
- rewards.length === 0 ||
- parseFloat(
- rewards[0]?.maxDecimals(4).toString().split(" ")[0]
- ) < 0.00001 ? (
- 0
- ) : (
- rewards[0]?.maxDecimals(4).toString()
- )}
-
- ) : (
-
-
-
- )}
- {(!rewards ||
- rewards.length !== 0 ||
- parseFloat(rewards[0]?.maxDecimals(4).toString().split(" ")[0]) >
- 0.00001) && (
-
- Claim
-
- )}
-
-
-
-
- View in Explorer for more Details
-
- {validator.jailed && (
-
- This validator is currently jailed. Redelegate your tokens.
-
- )}
-
- );
-};
diff --git a/packages/fetch-extension/src/pages/validator/validator-details/validatordetails.module.scss b/packages/fetch-extension/src/pages/validator/validator-details/validatordetails.module.scss
deleted file mode 100644
index 2d5000d514..0000000000
--- a/packages/fetch-extension/src/pages/validator/validator-details/validatordetails.module.scss
+++ /dev/null
@@ -1,74 +0,0 @@
-.col {
- text-align: center;
- display: flex;
- flex-direction: column;
- gap: 4px;
- font-size: 12px;
-}
-
-.title {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- width: 100%;
- border-bottom: 1px solid lightgray;
- font-size: 14px;
-}
-
-.label {
- font-size: 14px;
- font-weight: bold;
- text-transform: capitalize;
-}
-
-.address {
- font-style: italic;
- font-size: smaller;
-}
-
-.description {
- font-size: 14px;
- display: flex;
- flex-direction: column;
- width: 100%;
- border-bottom: 1px solid lightgray;
-}
-
-.details {
- display: flex;
- justify-content: space-between;
- width: 100%;
- border-bottom: 1px solid lightgray;
-}
-
-.item {
- display: flex;
- flex-direction: column;
- gap: 8px;
- width: 100%;
- padding: 10px;
- background: #ffffff;
- border-radius: 6px;
-}
-
-.tooltip {
- font-weight: 400;
- font-size: 10px;
- line-height: 10px;
-
- padding: 2px 4px;
-}
-.jailed {
- color: red;
- text-align: center;
- font-size: 10px;
-}
-.claimButton {
- font-weight: bold;
- cursor: pointer;
- padding: 0px 13px;
- text-decoration: underline;
- color: #3b82f6;
- border: none;
- background: transparent;
-}