"$0"
+ stakedInFiatCurrency !== undefined &&
+ stakedInFiatCurrency > "$0"
? require("@assets/svg/wireframe/legend-purple-long.svg")
: require("@assets/svg/wireframe/legend-purple.svg")
}
@@ -296,7 +308,8 @@ export const Stats = observer(
)}
{isLoaded ? (
- stakedInUSD !== undefined && stakedInUSD > "$0" ? (
+ stakedInFiatCurrency !== undefined &&
+ stakedInFiatCurrency > "$0" ? (
- {stakedInUSD}
+ {stakedInFiatCurrency}
) : null
) : (
@@ -315,7 +328,8 @@ export const Stats = observer(
"$0"
+ rewardsInFiatCurrency !== undefined &&
+ rewardsInFiatCurrency > "$0"
? require("@assets/svg/wireframe/legend-orange-long.svg")
: require("@assets/svg/wireframe/legend-orange.svg")
}
@@ -340,7 +354,8 @@ export const Stats = observer(
)}
{isLoaded ? (
- rewardsInUSD !== undefined && rewardsInUSD > "$0" ? (
+ rewardsInFiatCurrency !== undefined &&
+ rewardsInFiatCurrency > "$0" ? (
- {rewardsInUSD}
+ {rewardsInFiatCurrency}
) : null
) : (
diff --git a/packages/fetch-extension/src/pages-new/send/send-phase-2.tsx b/packages/fetch-extension/src/pages-new/send/send-phase-2.tsx
index a4f2663a48..805b9222cf 100644
--- a/packages/fetch-extension/src/pages-new/send/send-phase-2.tsx
+++ b/packages/fetch-extension/src/pages-new/send/send-phase-2.tsx
@@ -182,7 +182,7 @@ export const SendPhase2: React.FC
= observer(
new Int(0)
)
)}{" "}
- USD
+ {fiatCurrency.toUpperCase()}
{parseFloat(sendConfigs.amountConfig.amount)
diff --git a/packages/fetch-extension/src/pages-new/stake/dashboard/index.tsx b/packages/fetch-extension/src/pages-new/stake/dashboard/index.tsx
index 10628a507e..40888d9590 100644
--- a/packages/fetch-extension/src/pages-new/stake/dashboard/index.tsx
+++ b/packages/fetch-extension/src/pages-new/stake/dashboard/index.tsx
@@ -12,6 +12,7 @@ import { MyStakes } from "./my-stake/my-stakes";
import { observer } from "mobx-react-lite";
import { WalletStatus } from "@keplr-wallet/stores";
import { Skeleton } from "@components-v2/skeleton-loader";
+import { useLanguage } from "../../../languages";
export const Dashboard = observer(() => {
const { chainStore, accountStore, queriesStore, priceStore } = useStore();
@@ -23,6 +24,8 @@ export const Dashboard = observer(() => {
accountInfo.bech32Address
);
const balanceStakableQuery = balanceQuery.stakable;
+ const language = useLanguage();
+ const fiatCurrency = language.fiatCurrency;
const queryDelegations =
queries.cosmos.queryDelegations.getQueryBech32Address(
@@ -79,9 +82,15 @@ export const Dashboard = observer(() => {
const stakedPercentage = total ? (stakedBalInUI / total) * 100 : 0;
const rewardsPercentage = total ? (rewardsBalInUI / total) * 100 : 0;
- const stakableInUSD = priceStore.calculatePrice(stakable)?.toString();
- const stakedInUSD = priceStore.calculatePrice(stakedSum)?.toString();
- const rewardsInUSD = priceStore.calculatePrice(stakableReward)?.toString();
+ const stakableInFiatCurrency = priceStore
+ .calculatePrice(stakable, fiatCurrency)
+ ?.toString();
+ const stakedInFiatCurrency = priceStore
+ .calculatePrice(stakedSum, fiatCurrency)
+ ?.toString();
+ const rewardsInFiatCurrency = priceStore
+ .calculatePrice(stakableReward, fiatCurrency)
+ ?.toString();
const isLoaded =
accountInfo.walletStatus === WalletStatus.Loaded &&
@@ -118,7 +127,8 @@ export const Dashboard = observer(() => {
"$0"
+ stakableInFiatCurrency !== undefined &&
+ stakableInFiatCurrency > "$0"
? require("@assets/svg/wireframe/legend-light-purple-long.svg")
: require("@assets/svg/wireframe/legend-light-purple.svg")
}
@@ -143,7 +153,8 @@ export const Dashboard = observer(() => {
)}
{isLoaded ? (
- stakableInUSD !== undefined && stakableInUSD > "$0" ? (
+ stakableInFiatCurrency !== undefined &&
+ stakableInFiatCurrency > "$0" ? (
{
color: "rgba(255,255,255,0.6)",
}}
>
- {stakableInUSD}
+ {stakableInFiatCurrency}
) : null
) : (
@@ -162,7 +173,8 @@ export const Dashboard = observer(() => {
"$0"
+ stakedInFiatCurrency !== undefined &&
+ stakedInFiatCurrency > "$0"
? require("@assets/svg/wireframe/legend-purple-long.svg")
: require("@assets/svg/wireframe/legend-purple.svg")
}
@@ -188,7 +200,8 @@ export const Dashboard = observer(() => {
)}
{isLoaded ? (
- stakedInUSD !== undefined && stakedInUSD > "$0" ? (
+ stakedInFiatCurrency !== undefined &&
+ stakedInFiatCurrency > "$0" ? (
{
color: "rgba(255,255,255,0.6)",
}}
>
- {stakedInUSD}
+ {stakedInFiatCurrency}
) : null
) : (
@@ -207,7 +220,8 @@ export const Dashboard = observer(() => {
"$0"
+ rewardsInFiatCurrency !== undefined &&
+ rewardsInFiatCurrency > "$0"
? require("@assets/svg/wireframe/legend-orange-long.svg")
: require("@assets/svg/wireframe/legend-orange.svg")
}
@@ -232,7 +246,8 @@ export const Dashboard = observer(() => {
)}
{isLoaded ? (
- rewardsInUSD !== undefined && rewardsInUSD > "$0" ? (
+ rewardsInFiatCurrency !== undefined &&
+ rewardsInFiatCurrency > "$0" ? (
{
color: "rgba(255,255,255,0.6)",
}}
>
- {rewardsInUSD}
+ {rewardsInFiatCurrency}
) : null
) : (
diff --git a/packages/fetch-extension/src/pages-new/stake/dashboard/my-stake/my-stakes.tsx b/packages/fetch-extension/src/pages-new/stake/dashboard/my-stake/my-stakes.tsx
index dbf69ce73e..aee4e1232d 100644
--- a/packages/fetch-extension/src/pages-new/stake/dashboard/my-stake/my-stakes.tsx
+++ b/packages/fetch-extension/src/pages-new/stake/dashboard/my-stake/my-stakes.tsx
@@ -22,6 +22,7 @@ import { separateNumericAndDenom } from "@utils/format";
import { Dec } from "@keplr-wallet/unit";
import { TXNTYPE } from "../../../../config";
import { useDropdown } from "@components-v2/dropdown/dropdown-context";
+import { useLanguage } from "../../../../languages";
export const MyStakes = observer(
({
@@ -37,6 +38,9 @@ export const MyStakes = observer(
}) => {
const navigate = useNavigate();
const notification = useNotification();
+ const language = useLanguage();
+
+ const fiatCurrency = language.fiatCurrency;
const [_isWithdrawingRewards, setIsWithdrawingRewards] = useState(false);
const {
@@ -73,7 +77,8 @@ export const MyStakes = observer(
).stakableReward;
const pendingStakableRewardUSD = priceStore.calculatePrice(
- pendingStakableReward.shrink(true).maxDecimals(6).trim(true)
+ pendingStakableReward.shrink(true).maxDecimals(6).trim(true),
+ fiatCurrency
);
const { numericPart: totalNumber } = separateNumericAndDenom(
@@ -207,7 +212,9 @@ export const MyStakes = observer(
.trim(true)
.toString()
: totalNumber}{" "}
-
USD
+
+ {fiatCurrency.toUpperCase()}
+
diff --git a/packages/fetch-extension/src/pages-new/stake/dashboard/my-stake/my-validator.tsx b/packages/fetch-extension/src/pages-new/stake/dashboard/my-stake/my-validator.tsx
index 297d710ab1..9cf02df6a1 100644
--- a/packages/fetch-extension/src/pages-new/stake/dashboard/my-stake/my-validator.tsx
+++ b/packages/fetch-extension/src/pages-new/stake/dashboard/my-stake/my-validator.tsx
@@ -6,10 +6,14 @@ import { Staking } from "@keplr-wallet/stores";
import { useStore } from "../../../../stores";
import { useNavigate } from "react-router";
import { Dec } from "@keplr-wallet/unit";
+import { useLanguage } from "../../../../languages";
export const MyValidator = observer(() => {
const { chainStore, accountStore, queriesStore, priceStore, analyticsStore } =
useStore();
+ const language = useLanguage();
+
+ const fiatCurrency = language.fiatCurrency;
const navigate = useNavigate();
@@ -66,8 +70,9 @@ export const MyValidator = observer(() => {
unbondedValidators.getValidatorThumbnail(val.operator_address);
const amount = queryDelegations.getDelegationTo(val.operator_address);
- const amountUSD = priceStore.calculatePrice(
- amount.maxDecimals(5).trim(true).shrink(true)
+ const amountFiatCurrency = priceStore.calculatePrice(
+ amount.maxDecimals(5).trim(true).shrink(true),
+ fiatCurrency
);
const reward = queries.cosmos.queryRewards
@@ -132,10 +137,10 @@ export const MyValidator = observer(() => {
- {amountUSD && (
+ {amountFiatCurrency && (
- {amountUSD
+ {amountFiatCurrency
.shrink(true)
.maxDecimals(6)
.trim(true)
@@ -143,7 +148,7 @@ export const MyValidator = observer(() => {
{" "}
- {priceStore.defaultVsCurrency.toUpperCase()}
+ {fiatCurrency.toUpperCase()}
)}
diff --git a/packages/fetch-extension/src/pages-new/validator/delegate/index.tsx b/packages/fetch-extension/src/pages-new/validator/delegate/index.tsx
index 0a7bd2c328..75cef59125 100644
--- a/packages/fetch-extension/src/pages-new/validator/delegate/index.tsx
+++ b/packages/fetch-extension/src/pages-new/validator/delegate/index.tsx
@@ -15,6 +15,7 @@ import { useLocation, useNavigate } from "react-router";
import { Alert, FormGroup } from "reactstrap";
import { TXNTYPE } from "../../../config";
import { useStore } from "../../../stores";
+import { useLanguage } from "../../../languages";
import style from "./style.module.scss";
export const Delegate: FunctionComponent = observer(() => {
@@ -22,6 +23,8 @@ export const Delegate: FunctionComponent = observer(() => {
const validatorAddress = location.pathname.split("/")[2];
const navigate = useNavigate();
+ const language = useLanguage();
+ const fiatCurrency = language.fiatCurrency;
const {
chainStore,
@@ -34,7 +37,9 @@ export const Delegate: FunctionComponent = observer(() => {
const [isToggleClicked, setIsToggleClicked] = useState
(false);
- const [inputInUsd, setInputInUsd] = useState("");
+ const [inputInFiatCurrency, setInputInFiatCurrency] = useState<
+ string | undefined
+ >("");
const account = accountStore.getAccount(chainStore.current.chainId);
const queries = queriesStore.get(chainStore.current.chainId);
@@ -73,23 +78,23 @@ export const Delegate: FunctionComponent = observer(() => {
: new CoinPretty(sendConfigs.amountConfig.sendCurrency, new Int(0));
const convertToUsd = (currency: any) => {
- const value = priceStore.calculatePrice(currency);
+ const value = priceStore.calculatePrice(currency, fiatCurrency);
return value && value.shrink(true).maxDecimals(6).toString();
};
useEffect(() => {
const inputValueInUsd = convertToUsd(balance);
- setInputInUsd(inputValueInUsd);
+ setInputInFiatCurrency(inputValueInUsd);
}, [sendConfigs.amountConfig.amount]);
- const Usd = inputInUsd
- ? ` (${inputInUsd} ${priceStore.defaultVsCurrency.toUpperCase()})`
+ const FiatCurrency = inputInFiatCurrency
+ ? ` (${inputInFiatCurrency} ${fiatCurrency.toUpperCase()})`
: "";
const availableBalance = `${balance
.trim(true)
.shrink(true)
.maxDecimals(6)
- .toString()}${Usd}`;
+ .toString()}${FiatCurrency}`;
const bondedValidators = queries.cosmos.queryValidators.getQueryStatus(
Staking.BondStatus.Bonded
diff --git a/packages/fetch-extension/src/pages-new/validator/redelegate/index.tsx b/packages/fetch-extension/src/pages-new/validator/redelegate/index.tsx
index 591af97973..8c6f8981a5 100644
--- a/packages/fetch-extension/src/pages-new/validator/redelegate/index.tsx
+++ b/packages/fetch-extension/src/pages-new/validator/redelegate/index.tsx
@@ -21,6 +21,7 @@ import style from "./style.module.scss";
import { RedelegateValidatorDetail } from "./validator-detail";
import { TXNTYPE } from "../../../config";
import { useIntl } from "react-intl";
+import { useLanguage } from "../../../languages";
type Sort = "APR" | "Voting Power" | "Name";
@@ -28,6 +29,9 @@ export const Redelegate = observer(() => {
const location = useLocation();
const validatorAddress = location.pathname.split("/")[2];
+ const language = useLanguage();
+ const fiatCurrency = language.fiatCurrency;
+
const navigate = useNavigate();
const {
chainStore,
@@ -103,7 +107,9 @@ export const Redelegate = observer(() => {
const { amountConfig, memoConfig, feeConfig } = sendConfigs;
const [isToggleClicked, setIsToggleClicked] = useState(false);
- const [inputInUsd, setInputInUsd] = useState("");
+ const [inputInFiatCurrency, setInputInFiatCurrency] = useState<
+ string | undefined
+ >("");
const stakedAmount = queriesStore
.get(amountConfig.chainId)
@@ -138,24 +144,24 @@ export const Redelegate = observer(() => {
: new CoinPretty(sendConfigs.amountConfig.sendCurrency, new Int(0));
const convertToUsd = (currency: any) => {
- const value = priceStore.calculatePrice(currency);
+ const value = priceStore.calculatePrice(currency, fiatCurrency);
return value && value.shrink(true).maxDecimals(6).toString();
};
useEffect(() => {
const inputValueInUsd = convertToUsd(balance);
- setInputInUsd(inputValueInUsd);
+ setInputInFiatCurrency(inputValueInUsd);
}, [sendConfigs.amountConfig.amount]);
- const Usd = inputInUsd
- ? ` (${inputInUsd} ${priceStore.defaultVsCurrency.toUpperCase()})`
+ const FiatCurrency = inputInFiatCurrency
+ ? ` (${inputInFiatCurrency} ${fiatCurrency.toUpperCase()})`
: "";
const availableBalance = `${balance
.trim(true)
.shrink(true)
.maxDecimals(6)
- .toString()}${Usd}`;
+ .toString()}${FiatCurrency}`;
const notification = useNotification();
diff --git a/packages/fetch-extension/src/pages-new/validator/unstake/index.tsx b/packages/fetch-extension/src/pages-new/validator/unstake/index.tsx
index eb0b261770..72014ec759 100644
--- a/packages/fetch-extension/src/pages-new/validator/unstake/index.tsx
+++ b/packages/fetch-extension/src/pages-new/validator/unstake/index.tsx
@@ -21,10 +21,13 @@ import { Alert, FormGroup } from "reactstrap";
import { TXNTYPE } from "../../../config";
import { useStore } from "../../../stores";
import style from "./style.module.scss";
+import { useLanguage } from "../../../languages";
export const Unstake = observer(() => {
const location = useLocation();
const validatorAddress = location.pathname.split("/")[2];
+ const language = useLanguage();
+ const fiatCurrency = language.fiatCurrency;
const navigate = useNavigate();
const {
chainStore,
@@ -47,7 +50,9 @@ export const Unstake = observer(() => {
const { amountConfig, memoConfig, feeConfig } = sendConfigs;
const [isToggleClicked, setIsToggleClicked] = useState(false);
- const [inputInUsd, setInputInUsd] = useState("");
+ const [inputInFiatCurrency, setInputInFiatCurrency] = useState<
+ string | undefined
+ >("");
const intl = useIntl();
const error = amountConfig.error;
@@ -58,7 +63,7 @@ export const Unstake = observer(() => {
.getDelegationTo(validatorAddress);
const convertToUsd = (currency: any) => {
- const value = priceStore.calculatePrice(currency);
+ const value = priceStore.calculatePrice(currency, fiatCurrency);
return value && value.shrink(true).maxDecimals(6).toString();
};
@@ -77,18 +82,18 @@ export const Unstake = observer(() => {
useEffect(() => {
const inputValueInUsd = convertToUsd(balance);
- setInputInUsd(inputValueInUsd);
+ setInputInFiatCurrency(inputValueInUsd);
}, [sendConfigs.amountConfig.amount]);
- const Usd = inputInUsd
- ? ` (${inputInUsd} ${priceStore.defaultVsCurrency.toUpperCase()})`
+ const FiatCurrency = inputInFiatCurrency
+ ? ` (${inputInFiatCurrency} ${fiatCurrency.toUpperCase()})`
: "";
const availableBalance = `${balance
.trim(true)
.shrink(true)
.maxDecimals(6)
- .toString()}${Usd}`;
+ .toString()}${FiatCurrency}`;
const errorText: string | undefined = useMemo(() => {
if (error) {
diff --git a/packages/fetch-extension/src/utils/fetch-proposals.ts b/packages/fetch-extension/src/utils/fetch-proposals.ts
index 75e1799e96..aa0928933a 100644
--- a/packages/fetch-extension/src/utils/fetch-proposals.ts
+++ b/packages/fetch-extension/src/utils/fetch-proposals.ts
@@ -13,6 +13,12 @@ export const fetchProposals = async (chainId: string) => {
.then((response) => response.data)
.catch((e) => console.log(e));
+ if (chainId === "test-local")
+ return await axios
+ .get("http://localhost:1317/cosmos/gov/v1beta1/proposals")
+ .then((response) => response.data)
+ .catch((e) => console.log(e));
+
if (chainId === "test")
return await axios
.get("http://34.34.58.246:1317/cosmos/gov/v1beta1/proposals")
diff --git a/packages/fetch-extension/src/utils/format.ts b/packages/fetch-extension/src/utils/format.ts
index 3a4627d638..8b477eadfd 100644
--- a/packages/fetch-extension/src/utils/format.ts
+++ b/packages/fetch-extension/src/utils/format.ts
@@ -131,9 +131,18 @@ export const separateNumericAndDenom = (value: any) => {
};
export const parseDollarAmount = (dollarString: any) => {
- const match = dollarString.match(/[0-9.]+/);
+ const match = dollarString.match(
+ /(?<=\D|\b)(\d{1,2}(?:,\d{2})*(?:,\d{3})*)(?:\.\d+)?(?=\b|\D)/g
+ );
+ let cleanedMatches = [];
+
if (match) {
- return parseFloat(match[0]);
+ // removes commas from matched result
+ cleanedMatches = match.map((match: any) => match.replace(/,/g, ""));
+ }
+
+ if (cleanedMatches && cleanedMatches.length > 0) {
+ return parseFloat(cleanedMatches[0]);
}
return NaN;
};
diff --git a/packages/stores/src/account/cosmos.ts b/packages/stores/src/account/cosmos.ts
index 9323ba52e0..05fd1bf1a3 100644
--- a/packages/stores/src/account/cosmos.ts
+++ b/packages/stores/src/account/cosmos.ts
@@ -48,8 +48,10 @@ import { MakeTxResponse, ProtoMsgsOrWithAminoMsgs } from "./types";
import {
getEip712TypedDataBasedOnChainId,
getNodes,
+ getProposalNode,
txEventsWithPreOnFulfill,
updateNodeOnTxnCompleted,
+ updateProposalNodeOnTxnCompleted,
} from "./utils";
import { ExtensionOptionsWeb3Tx } from "@keplr-wallet/proto-types/ethermint/types/v1/web3";
import { MsgRevoke } from "@keplr-wallet/proto-types/cosmos/authz/v1beta1/tx";
@@ -88,6 +90,33 @@ export interface Node {
};
}
+export interface ProposalNode {
+ type: string;
+ block: {
+ timestamp: string;
+ __typename: string;
+ };
+ transaction: {
+ status: string;
+ id: string;
+ log: [];
+ __typename: string;
+ fees: string;
+ gasUsed: string;
+ chainId: string;
+ memo: string;
+ };
+ messages: {
+ json: string;
+ typeUrl: string;
+ __typename: string;
+ };
+ proposalId: string;
+ option: string | undefined;
+ id: string;
+ __typename: string;
+}
+
export const CosmosAccount = {
use(options: {
msgOptsCreator?: (
@@ -400,6 +429,7 @@ export class CosmosAccountImpl {
let txHash: Uint8Array;
let signDoc: StdSignDoc;
let txId: string;
+ let proposalNode: ProposalNode;
try {
if (typeof msgs === "function") {
@@ -443,6 +473,17 @@ export class CosmosAccountImpl {
},
};
+ if (type === "govVote") {
+ proposalNode = getProposalNode({
+ txId,
+ signDoc,
+ type,
+ fee,
+ memo,
+ nodes,
+ });
+ this.activityStore.addProposalNode(proposalNode);
+ }
this.activityStore.addNode(newNode);
this.activityStore.addPendingTxn({ id: txId, type });
} catch (e: any) {
@@ -502,6 +543,13 @@ export class CosmosAccountImpl {
.traceTx(txHash)
.then((tx) => {
txTracer.close();
+ if (type === "govVote") {
+ updateProposalNodeOnTxnCompleted(
+ tx,
+ proposalNode,
+ this.activityStore
+ );
+ }
//update node's gas, amount and status on completed
updateNodeOnTxnCompleted(type, tx, txId, this.activityStore);
this.activityStore.removePendingTxn(txId);
@@ -537,6 +585,12 @@ export class CosmosAccountImpl {
.catch(() => {
this.activityStore.removePendingTxn(txId);
this.activityStore.setTxnStatus(txId, "Unconfirmed");
+ if (type === "govVote") {
+ this.activityStore.setProposalTxnStatus(
+ proposalNode.id,
+ "Unconfirmed"
+ );
+ }
this.base.setTxTypeInProgress("");
this.activityStore.setIsNodeUpdated(true);
});
diff --git a/packages/stores/src/account/utils.ts b/packages/stores/src/account/utils.ts
index e2113b9f53..12dadcd446 100644
--- a/packages/stores/src/account/utils.ts
+++ b/packages/stores/src/account/utils.ts
@@ -1,5 +1,6 @@
import { EthermintChainIdHelper } from "@keplr-wallet/cosmos";
import { ProtoMsgsOrWithAminoMsgs } from "./types";
+import { ProposalNode } from "./cosmos";
export function txEventsWithPreOnFulfill(
onTxEvents:
@@ -294,3 +295,83 @@ export const updateNodeOnTxnCompleted = (
activityStore.setIsNodeUpdated(true);
};
+
+export const updateProposalNodeOnTxnCompleted = (
+ tx: any,
+ proposalNode: ProposalNode,
+ activityStore: any
+) => {
+ const txId = proposalNode.id;
+
+ const updatedProposalNode = {
+ ...proposalNode,
+ transaction: {
+ ...proposalNode.transaction,
+ log: tx.log,
+ },
+ };
+
+ activityStore.setProposalNode(txId, updatedProposalNode);
+
+ // if txn fails, it will have tx.code.
+ if (tx.code) {
+ activityStore.setProposalTxnStatus(txId, "Failed");
+ } else {
+ activityStore.setProposalTxnStatus(txId, "Success");
+ }
+};
+
+export const getProposalNode = ({
+ txId,
+ signDoc,
+ type,
+ fee,
+ memo,
+ nodes,
+}: {
+ txId: string;
+ signDoc: any;
+ type: string;
+ fee: any;
+ memo: string;
+ nodes: Array;
+}): ProposalNode => {
+ const option = Number(signDoc.msgs[0].value.option);
+ const optionText = (() => {
+ switch (option) {
+ case 1:
+ return "YES";
+ case 2:
+ return "ABSTAIN";
+ case 3:
+ return "NO";
+ case 4:
+ return "NO_WITH_VETO";
+ }
+ })();
+
+ const proposalNode: ProposalNode = {
+ type,
+ block: {
+ timestamp: new Date().toJSON(),
+ __typename: "Block",
+ },
+ transaction: {
+ status: "Pending",
+ id: txId,
+ log: [],
+ fees: JSON.stringify(signDoc.fee.amount),
+ chainId: signDoc.chain_id,
+ gasUsed: fee.gas,
+ memo: memo,
+ __typename: "Transaction",
+ },
+ messages: nodes[0],
+ proposalId: signDoc.msgs[0].value.proposal_id,
+ option: optionText,
+ id: `${txId}-0`,
+ __typename: "GovProposalVote",
+ };
+
+ return proposalNode;
+};
diff --git a/packages/stores/src/activity/index.ts b/packages/stores/src/activity/index.ts
index 4a2756bcd3..b354612adc 100644
--- a/packages/stores/src/activity/index.ts
+++ b/packages/stores/src/activity/index.ts
@@ -1,7 +1,10 @@
import { KVStore, toGenerator } from "@keplr-wallet/common";
import { TendermintTxTracer } from "@keplr-wallet/cosmos";
import { action, flow, makeObservable, observable } from "mobx";
-import { updateNodeOnTxnCompleted } from "../account";
+import {
+ updateNodeOnTxnCompleted,
+ updateProposalNodeOnTxnCompleted,
+} from "../account";
import { ChainGetter } from "src/common";
enum TXNTYPE {
@@ -20,6 +23,9 @@ export class ActivityStore {
@observable
protected nodes: any = {};
+ @observable
+ protected proposalNodes: any = {};
+
@observable
protected address: string = "";
@@ -54,6 +60,14 @@ export class ActivityStore {
this.saveNodes();
}
+ // updates or adds new nodes to the proposal list
+ updateProposalNodes(nodes: any) {
+ const updatedNodes = { ...this.proposalNodes, ...nodes };
+ this.setProposalNodes(updatedNodes);
+
+ this.saveProposalNodes();
+ }
+
getSortedNodesByTimeStamps() {
const sortedNodes = Object.values(this.nodes).sort((a: any, b: any) => {
if (a.block.timestamp < b.block.timestamp) {
@@ -68,6 +82,22 @@ export class ActivityStore {
return sortedNodes;
}
+ getSortedProposalNodesByTimeStamps() {
+ const sortedNodes = Object.values(this.proposalNodes).sort(
+ (a: any, b: any) => {
+ if (a.block.timestamp < b.block.timestamp) {
+ return 1;
+ } else if (a.block.timestamp > b.block.timestamp) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+ );
+
+ return sortedNodes;
+ }
+
@flow
*saveNodes() {
const currNodes = Object.keys(this.nodes).length > 0 ? this.nodes : {};
@@ -89,6 +119,27 @@ export class ActivityStore {
}
}
+ @flow
+ *saveProposalNodes() {
+ const currNodes =
+ Object.keys(this.proposalNodes).length > 0 ? this.proposalNodes : {};
+ let oldNodes = yield* toGenerator(
+ this.kvStore.get(
+ `extension_gov_proposal_nodes-${this.address}-${this.chainId}`
+ )
+ );
+ if (oldNodes === undefined || oldNodes === null) {
+ oldNodes = {};
+ }
+
+ if (Object.values(currNodes).length >= Object.values(oldNodes).length) {
+ yield this.kvStore.set(
+ `extension_gov_proposal_nodes-${this.address}-${this.chainId}`,
+ JSON.parse(JSON.stringify(currNodes))
+ );
+ }
+ }
+
@flow
*saveAddress() {
yield this.kvStore.set("extension_activity_address", this.address);
@@ -152,6 +203,14 @@ export class ActivityStore {
);
this.nodes = savedNodes !== undefined ? savedNodes : {};
+ const savedProposalNodes = yield* toGenerator(
+ this.kvStore.get(
+ `extension_gov_proposal_nodes-${this.address}-${this.chainId}`
+ )
+ );
+ this.proposalNodes =
+ savedProposalNodes !== undefined ? savedProposalNodes : {};
+
const savedPendingTxn = yield* toGenerator(
this.kvStore.get(
`extension_pending_txn-${this.address}-${this.chainId}`
@@ -185,6 +244,15 @@ export class ActivityStore {
});
});
+ Object.values(this.proposalNodes).map((node: any) => {
+ const txId = node.transaction.id;
+ const txHash = Uint8Array.from(Buffer.from(txId, "hex"));
+ txTracer.traceTx(txHash).then(async (tx) => {
+ updateProposalNodeOnTxnCompleted(tx, this.proposalNodes[node.id], this);
+ this.removePendingTxn(txId);
+ });
+ });
+
if (Object.keys(this.pendingTxn).length === 0) {
this.resetPendingTxnTypes();
}
@@ -195,6 +263,11 @@ export class ActivityStore {
this.updateNodes({ [node.id]: node });
}
+ @action
+ addProposalNode(node: any) {
+ this.updateProposalNodes({ [node.id]: node });
+ }
+
@action
addPendingTxn(node: any) {
const newNode = {
@@ -256,6 +329,15 @@ export class ActivityStore {
this.saveNodes();
}
+ @action
+ setProposalTxnStatus(
+ nodeId: any,
+ status: "Pending" | "Success" | "Failed" | "Unconfirmed"
+ ) {
+ this.proposalNodes[nodeId].transaction.status = status;
+ this.saveProposalNodes();
+ }
+
@action
updateTxnBalance(nodeId: any, amount: number) {
this.nodes[nodeId].balanceOffset = amount;
@@ -297,6 +379,11 @@ export class ActivityStore {
this.nodes = nodes;
}
+ @action
+ setProposalNodes(nodes: any) {
+ this.proposalNodes = nodes;
+ }
+
@action
setPendingTxn(nodes: any) {
this.pendingTxn = nodes;
@@ -314,6 +401,11 @@ export class ActivityStore {
this.nodes[id] = node;
}
+ @action
+ setProposalNode(id: any, node: any) {
+ this.proposalNodes[id] = node;
+ }
+
@action
setAddress(address: string) {
this.address = address;
@@ -335,6 +427,10 @@ export class ActivityStore {
return this.nodes;
}
+ get getProposalNodes() {
+ return this.proposalNodes;
+ }
+
get checkIsNodeUpdated() {
return this.isNodeUpdated;
}
@@ -358,4 +454,8 @@ export class ActivityStore {
get sortedNodes() {
return this.getSortedNodesByTimeStamps();
}
+
+ get sortedNodesProposals() {
+ return this.getSortedProposalNodesByTimeStamps();
+ }
}