Skip to content

Commit

Permalink
fix: resolve UAT issues
Browse files Browse the repository at this point in the history
  • Loading branch information
icfor committed Apr 15, 2024
1 parent cefe65f commit 5f86e52
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 45 deletions.
3 changes: 2 additions & 1 deletion public/locales/en/staking.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@
"stakingModal": {
"amountError": {
"invalid": "You have to input a valid amount",
"noBalance": "You don't have any tokens to stake"
"noBalance": "You don't have any tokens to stake",
"notEnough": "The minimum staking amount is {{amount}}"
},
"available": "Available",
"complete": {
Expand Down
3 changes: 2 additions & 1 deletion public/locales/zh-CN/staking.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@
"stakingModal": {
"amountError": {
"invalid": "您必须输入有效金额",
"noBalance": "您没有任何通证可供质押"
"noBalance": "您没有任何通证可供质押",
"notEnough": "最低质押金额为{{amount}}"
},
"available": "可用通证",
"complete": {
Expand Down
3 changes: 2 additions & 1 deletion public/locales/zh-HK/staking.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@
"stakingModal": {
"amountError": {
"invalid": "您必須輸入有效金額",
"noBalance": "您沒有任何通證可供質押"
"noBalance": "您沒有任何通證可供質押",
"notEnough": "最低質押金金額為{{amount}}"
},
"available": "可用通證",
"complete": {
Expand Down
71 changes: 44 additions & 27 deletions src/screens/staking/components/staking_section/staking_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ import {
} from "@src/screens/staking/lib/staking_sdk/context/actions";
import { getSelectedAccount } from "@src/screens/staking/lib/staking_sdk/context/selectors";
import type { StakingNetworkInfo } from "@src/screens/staking/lib/staking_sdk/core";
import { networksWithMemo } from "@src/screens/staking/lib/staking_sdk/core";
import { mainNetworkDenom } from "@src/screens/staking/lib/staking_sdk/core/base";
import { solanaNetworks } from "@src/screens/staking/lib/staking_sdk/core/solana";
import { formatCoin } from "@src/screens/staking/lib/staking_sdk/formatters";
import { getAccountNormalisedBalance } from "@src/screens/staking/lib/staking_sdk/utils/accounts";
import {
getEmptyCoin,
getIsCoin,
normaliseCoin,
} from "@src/screens/staking/lib/staking_sdk/utils/coins";
import { getUnbondingTimeForNetwork } from "@src/screens/staking/lib/staking_sdk/utils/networks";
import {
Expand All @@ -38,6 +40,7 @@ import {
} from "@src/screens/staking/lib/staking_sdk/utils/storage";
import {
MAX_MEMO,
minimumStakeAmountMap,
stakeAmount,
} from "@src/screens/staking/lib/staking_sdk/wallet_operations";
import { StakeError } from "@src/screens/staking/lib/staking_sdk/wallet_operations/base";
Expand Down Expand Up @@ -98,6 +101,8 @@ const StakingModal = () => {

if (!account) return null;

const hasMemo = networksWithMemo.has(account.networkId);

const amountNum = new BigNumber(amount);

const isValidAmount =
Expand All @@ -114,6 +119,18 @@ const StakingModal = () => {
return t("stakingModal.amountError.noBalance");
}

const minimumStakeAmount = minimumStakeAmountMap[selectedAccount.networkId];

if (minimumStakeAmount) {
const normalised = normaliseCoin(minimumStakeAmount);

if (amountNum.lt(normalised.amount)) {
return t("stakingModal.amountError.notEnough", {
amount: formatCoin(normalised),
});
}
}

if (!isValidAmount) {
return t("stakingModal.amountError.invalid");
}
Expand Down Expand Up @@ -144,9 +161,7 @@ const StakingModal = () => {
isLoading ||
!isValidAmount ||
amountError ||
memoError ||
newAmountError ||
newMemoError
(hasMemo && (memoError || newAmountError || newMemoError))
)
return;

Expand Down Expand Up @@ -372,31 +387,33 @@ const StakingModal = () => {
</ModalError>
)}
</div>
<div className={styles.group}>
<Label>{t("stakingModal.memo")}</Label>
<FormInput
className={styles.input}
disabled={isLoading}
fullWidth
noFocusEffect
noMargin
onBlur={() => {
if (newMemoError !== memoError) {
setMemoError(newMemoError);
}
}}
onChange={(e) => {
if (memoError) {
setMemoError("");
}
{networksWithMemo.has(account.networkId) && (
<div className={styles.group}>
<Label>{t("stakingModal.memo")}</Label>
<FormInput
className={styles.input}
disabled={isLoading}
fullWidth
noFocusEffect
noMargin
onBlur={() => {
if (newMemoError !== memoError) {
setMemoError(newMemoError);
}
}}
onChange={(e) => {
if (memoError) {
setMemoError("");
}

setMemo(e.target.value);
}}
placeholder={t("optionalInput")}
value={memo}
/>
{!!memoError && <ModalError>{memoError}</ModalError>}
</div>
setMemo(e.target.value);
}}
placeholder={t("optionalInput")}
value={memo}
/>
{!!memoError && <ModalError>{memoError}</ModalError>}
</div>
)}
<HighlightButton
disabled={!!amountError || !!memoError || isLoading}
onClick={onSubmit}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
getStakeAccountsForNetwork,
} from "@src/screens/staking/lib/staking_sdk/context/selectors";
import type { StakingNetworkInfo } from "@src/screens/staking/lib/staking_sdk/core";
import { networksWithMemo } from "@src/screens/staking/lib/staking_sdk/core";
import { mainNetworkDenom } from "@src/screens/staking/lib/staking_sdk/core/base";
import { solanaNetworks } from "@src/screens/staking/lib/staking_sdk/core/solana";
import { formatCoin } from "@src/screens/staking/lib/staking_sdk/formatters";
Expand Down Expand Up @@ -138,11 +139,13 @@ const UnstakingModal = () => {
? getStakeAccountsForNetwork(
stakingRef.current.state,
selectedAccount.networkId,
account?.address,
)
: []
).filter((acc) => ["activating", "active"].includes(acc.status));

const onClose = () => setSelectedAccount(stakingRef.current, null, null);
const hasMemo = account ? networksWithMemo.has(account?.networkId) : false;

const onSubmit = (e: any) => {
e?.preventDefault();
Expand All @@ -160,7 +163,7 @@ const UnstakingModal = () => {
}

const hasInputError =
amountError || memoError || newAmountError || newMemoError;
amountError || newAmountError || (hasMemo && (newMemoError || memoError));

if (
!selectedAccount ||
Expand Down Expand Up @@ -417,7 +420,10 @@ const UnstakingModal = () => {
ns="staking"
/>
</li>
<li>{t("unstakingModal.info3")}</li>
{!!selectedAccount?.networkId &&
!solanaNetworks.has(selectedAccount.networkId) && (
<li>{t("unstakingModal.info3")}</li>
)}
<li>{t("unstakingModal.info4")}</li>
</ul>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const WithdrawUnstakedModal = () => {
? getStakeAccountsForNetwork(
stakingRef.current.state,
selectedAccount.networkId,
address,
)
: []
).filter((acc) => acc.status === "inactive");
Expand Down
2 changes: 2 additions & 0 deletions src/screens/staking/lib/staking_sdk/context/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ export const getAccountsForNetwork = (
export const getStakeAccountsForNetwork = (
state: StakingState,
network: StakingNetworkId,
parentAddress?: string,
) => {
const accounts = getAccountsForNetwork(state, network);
const uniqueAccounts = new Set<string>();

return accounts
.filter(parentAddress ? (acc) => acc.address === parentAddress : () => true)
.map((account) => account.info?.stakeAccounts)
.flat()
.filter((a): a is StakeAccount => !!a)
Expand Down
2 changes: 2 additions & 0 deletions src/screens/staking/lib/staking_sdk/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export const networksWithStakeAccounts = new Set([
...Array.from(solanaNetworks),
]);

export const networksWithMemo = new Set([...Array.from(cosmosStakingNetworks)]);

export const walletsSupported = new Set([
...Array.from(cosmosWallets),
...Array.from(solanaWallets),
Expand Down
1 change: 0 additions & 1 deletion src/screens/staking/lib/staking_sdk/utils/coins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ const denomMap: Record<DenomToNormalise, [CoinDenom, number]> = {
ADYM: [CoinDenom.DYM, aExp],
AISLM: [CoinDenom.ISLM, aExp],
// Because inj != INJ, this needs to keep the lower case, it is handled when
// normalising the coin
inj: [CoinDenom.INJ, exp0],
LAMPORTS: [CoinDenom.SOL, nExp],
PPICA: [CoinDenom.PICA, pExp],
Expand Down
7 changes: 7 additions & 0 deletions src/screens/staking/lib/staking_sdk/wallet_operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
import {
disconnectPhantom,
disconnectSolflare,
minimumSolanaStakeAmount,
stakeAmountSolana,
tryToConnectPhantom,
tryToConnectSolflare,
Expand Down Expand Up @@ -182,3 +183,9 @@ export const suggestAddWalletNetwork = (
) => {
suggestAddCosmosWalletNetwork(context, networkId);
};

export const minimumStakeAmountMap: {
[key in StakingNetworkId]?: Coin | undefined;
} = {
...minimumSolanaStakeAmount,
};
46 changes: 34 additions & 12 deletions src/screens/staking/lib/staking_sdk/wallet_operations/solana.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import {
Transaction,
} from "@solana/web3.js";
import Solflare from "@solflare-wallet/sdk";
import BigNumber from "bignumber.js";

import { toastError } from "@src/components/notification";

import type { TStakingContext } from "../context";
import { fetchAccountData, setUserWallet } from "../context/actions";
import type { Account } from "../core";
import type { Coin } from "../core/base";
import { ENABLE_TESTNETS, StakingNetworkId, WalletId } from "../core/base";
import { solanaNetworks } from "../core/solana";
import { stakingClient } from "../staking_client";
Expand Down Expand Up @@ -140,7 +142,14 @@ export const tryToConnectSolflare = async (
await Promise.all([
hasMainnetWallet ? mainnetWallet.connect() : Promise.resolve(),
hasDevnetWallet ? devnetWallet.connect() : Promise.resolve(),
]);
]).catch((err) => {
if (!err) {
// This means that the user closed the popup or rejected the connection
resolve(false);
}

reject(err);
});
});
};

Expand All @@ -160,7 +169,11 @@ export const tryToConnectPhantom = async (
const resp = await provider.connect();

publicKey = resp.publicKey.toString();
} catch (error) {
} catch (error: any) {
if (error?.message?.includes("User rejected the request")) {
return false;
}

toastError({
title: walletErrorMap.phantomCreateWallet,
});
Expand Down Expand Up @@ -211,9 +224,15 @@ export const tryToConnectPhantom = async (
};

// In mainnet less than 0.01 SOL it gives an error from the wallet estimation.
const minimumStakeAmount: { [key in StakingNetworkId]?: number } = {
[StakingNetworkId.Solana]: LAMPORTS_PER_SOL * 0.01,
[StakingNetworkId.SolanaDevnet]: LAMPORTS_PER_SOL * 0.001,
export const minimumSolanaStakeAmount: { [key in StakingNetworkId]?: Coin } = {
[StakingNetworkId.Solana]: {
amount: "0.01",
denom: "SOL",
},
[StakingNetworkId.SolanaDevnet]: {
amount: "0.001",
denom: "SOL",
},
};

type WalletApi = {
Expand Down Expand Up @@ -256,20 +275,23 @@ export const stakeAmountSolana = async ({

const stakeKeyPair = Keypair.generate();

const amountToStake = Number(amount) * LAMPORTS_PER_SOL;
const minimumAmount = minimumStakeAmount[account.networkId] || 0;
const minimumAmount = minimumSolanaStakeAmount[account.networkId] || {
amount: "0",
denom: "SOL",
};

const amountBN = new BigNumber(amount);

if (amountToStake < minimumAmount) {
if (amountBN.lt(normaliseCoin(minimumAmount).amount)) {
return {
coin: normaliseCoin({
amount: minimumAmount.toString(),
denom: "LAMPORTS",
}),
coin: minimumAmount,
error: StakeError.MinimumAmount,
success: false,
};
}

const amountToStake = amountBN.times(LAMPORTS_PER_SOL).toNumber();

const newTx = StakeProgram.createAccount({
authorized: new Authorized(accountKey, accountKey),
fromPubkey: accountKey,
Expand Down

0 comments on commit 5f86e52

Please sign in to comment.