diff --git a/src/components/dapp-staking/stake-manage/StakeForm.vue b/src/components/dapp-staking/stake-manage/StakeForm.vue
index dfce0944b..ef48a8b36 100644
--- a/src/components/dapp-staking/stake-manage/StakeForm.vue
+++ b/src/components/dapp-staking/stake-manage/StakeForm.vue
@@ -70,6 +70,12 @@
:set-selected-gas="setSelectedTip"
/>
+
+
+ ・
+ {{ $t(warningMsg) }}
+
+
{{ $t(errMsg) }}
@@ -136,6 +142,9 @@ export default defineComponent({
getTokenImage({ isNativeToken: true, symbol: nativeTokenSymbol.value })
);
const { selectedTip, nativeTipPrice, setSelectedTip } = useGasPrice();
+ const warningMsg = t('dappStaking.error.warningLeaveMinAmount', {
+ symbol: nativeTokenSymbol.value,
+ });
const inputHandler = (event: any): void => {
amount.value = event.target.value;
@@ -151,7 +160,12 @@ export default defineComponent({
});
const toMaxAmount = (): void => {
- amount.value = maxAmount.value;
+ const maximumAmount = ethers.utils.parseEther(maxAmount.value);
+ // MEMO: it leave 10ASTR in the account so it will keep the balance for longer period.
+ const leaveAmount = ethers.utils.parseEther('10');
+ amount.value = truncate(
+ ethers.utils.formatEther(maximumAmount.sub(leaveAmount).toString())
+ ).toString();
};
const formattedMinStaking = computed(() => {
@@ -166,11 +180,15 @@ export default defineComponent({
const stakingAmount = inputAmount + stakedAmount;
const isNotEnoughMinAmount = formattedMinStaking.value > stakingAmount;
+ const formatInputAmount = ethers.utils.parseEther(inputAmount.toString());
+ const maximumAmount = ethers.utils.parseEther(maxAmount.value);
+ const leaveAmount = ethers.utils.parseEther('10');
+
if (!inputAmount) {
return '';
}
- if (isNotEnoughMinAmount) {
+ if (isNotEnoughMinAmount || maximumAmount.sub(formatInputAmount).lte(leaveAmount)) {
return t('dappStaking.error.notEnoughMinAmount', {
amount: formattedMinStaking.value,
symbol: nativeTokenSymbol.value,
@@ -209,6 +227,7 @@ export default defineComponent({
amount,
errMsg,
maxAmount,
+ warningMsg,
setSelectedTip,
toMaxAmount,
getShortenAddress,
diff --git a/src/components/dapp-staking/stake-manage/StakeManage.vue b/src/components/dapp-staking/stake-manage/StakeManage.vue
index a9c0a09a9..5f61c6e19 100644
--- a/src/components/dapp-staking/stake-manage/StakeManage.vue
+++ b/src/components/dapp-staking/stake-manage/StakeManage.vue
@@ -59,7 +59,6 @@ import { Path } from 'src/router';
import { useStore } from 'src/store';
import { DappCombinedInfo } from 'src/v2/models';
import { computed, defineComponent, ref, watch } from 'vue';
-import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
export type StakeRightUi = 'information' | 'select-funds-from';
@@ -76,8 +75,6 @@ export default defineComponent({
setup() {
const isModalSelectFunds = ref(false);
const rightUi = ref('information');
-
- const { t } = useI18n();
const { screenSize, width } = useBreakpoints();
const route = useRoute();
useDappRedirect();
diff --git a/src/components/dapp-staking/stake-manage/styles/stake-form.scss b/src/components/dapp-staking/stake-manage/styles/stake-form.scss
index 7313528be..1d6287630 100644
--- a/src/components/dapp-staking/stake-manage/styles/stake-form.scss
+++ b/src/components/dapp-staking/stake-manage/styles/stake-form.scss
@@ -39,17 +39,41 @@
}
.row--box-error {
- padding: 10px 20px;
+ display: flex;
+ flex-direction: column;
+ row-gap: 6px;
+ padding: 8px 16px;
+ margin-bottom: 5px;
border-radius: 6px;
width: 344px;
- margin-bottom: 24px;
border: 1px solid $warning-red;
background: $box-red;
- text-align: left;
@media (min-width: $sm) {
width: 412px;
}
}
+.row--box-warning {
+ display: flex;
+ flex-direction: column;
+ row-gap: 6px;
+ border: 1px solid $border-yellow;
+ padding: 8px 16px;
+ width: 344px;
+ border-radius: 6px;
+ background: $transparent-yellow;
+ @media (min-width: $sm) {
+ width: 412px;
+ }
+}
+.text--dot {
+ font-size: 24px;
+ font-weight: 700;
+}
+.column--title {
+ display: flex;
+ align-items: center;
+ column-gap: 10px;
+}
.box__row {
display: flex;
diff --git a/src/hooks/dapps-staking/useStake.ts b/src/hooks/dapps-staking/useStake.ts
index ce1f7db10..972333ea8 100644
--- a/src/hooks/dapps-staking/useStake.ts
+++ b/src/hooks/dapps-staking/useStake.ts
@@ -8,7 +8,10 @@ import { container } from 'src/v2/common';
import { IDappStakingService } from 'src/v2/services';
import { Symbols } from 'src/v2/symbols';
import { computed, ref, watch } from 'vue';
+import { useNetworkInfo } from 'src/hooks';
+import { useStore } from 'src/store';
import { useRouter, useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
export function useStake() {
const router = useRouter();
@@ -17,6 +20,9 @@ export function useStake() {
const { stakingList } = useStakingList();
const isStakePage = computed(() => route.fullPath.includes('stake'));
const addressTransferFrom = ref(currentAccount.value);
+ const { t } = useI18n();
+ const store = useStore();
+ const { nativeTokenSymbol } = useNetworkInfo();
const setAddressTransferFrom = (address: string) => {
addressTransferFrom.value = address;
@@ -50,6 +56,17 @@ export function useStake() {
}) => {
const stakeAmount = new BN(ethers.utils.parseEther(amount).toString());
const dappStakingService = container.get(Symbols.DappStakingService);
+ const balance = new BN(formattedTransferFrom.value.item?.balance || '0');
+ if (balance.lt(stakeAmount)) {
+ store.dispatch('general/showAlertMsg', {
+ msg: t('dappStaking.error.invalidBalance', {
+ symbol: nativeTokenSymbol.value,
+ }),
+ alertType: 'error',
+ });
+ return;
+ }
+
if (formattedTransferFrom.value.isNominationTransfer) {
if (!formattedTransferFrom.value.item) return;
await dappStakingService.nominationTransfer({
diff --git a/src/hooks/useClaimAll.ts b/src/hooks/useClaimAll.ts
index fe059ab9d..9b986d300 100644
--- a/src/hooks/useClaimAll.ts
+++ b/src/hooks/useClaimAll.ts
@@ -6,14 +6,16 @@ import {
import { ISubmittableResult } from '@polkadot/types/types';
import { BN } from '@polkadot/util';
import { $api } from 'boot/api';
-import { useCurrentEra } from 'src/hooks';
+import { useCurrentEra, useBalance } from 'src/hooks';
import { displayCustomMessage, TxType } from 'src/hooks/custom-signature/message';
import { useStore } from 'src/store';
import { container } from 'src/v2/common';
import { DappCombinedInfo } from 'src/v2/models/DappsStaking';
import { IDappStakingService } from 'src/v2/services';
import { Symbols } from 'src/v2/symbols';
+import { ethers } from 'ethers';
import { computed, ref, watchEffect } from 'vue';
+import { useNetworkInfo } from 'src/hooks';
import { useI18n } from 'vue-i18n';
const MAX_BATCH_WEIGHT = new BN('50000000000');
@@ -31,6 +33,16 @@ export function useClaimAll() {
const isSendingTx = computed(() => store.getters['general/isLoading']);
const { t } = useI18n();
const { era } = useCurrentEra();
+ const selectedAddress = computed(() => store.getters['general/selectedAddress']);
+ const { accountData } = useBalance(selectedAddress);
+ const { nativeTokenSymbol } = useNetworkInfo();
+
+ const transferableBalance = computed(() => {
+ const balance = accountData.value
+ ? ethers.utils.formatEther(accountData.value.getUsableTransactionBalance().toString())
+ : '0';
+ return Number(balance);
+ });
watchEffect(async () => {
try {
@@ -103,6 +115,22 @@ export function useClaimAll() {
`Batch weight: ${totalWeight.toString()}, transactions no. ${txsToExecute.length}`
);
const transaction = api.tx.utility.batch(txsToExecute);
+ const info = await api.tx.utility.batch(txsToExecute).paymentInfo(senderAddress.value);
+ const partialFee = info.partialFee.toBn();
+ const balance = new BN(
+ ethers.utils.parseEther(transferableBalance.value.toString()).toString()
+ );
+
+ if (balance.sub(partialFee.muln(1.5)).isNeg()) {
+ store.dispatch('general/showAlertMsg', {
+ msg: t('dappStaking.error.invalidBalance', {
+ symbol: nativeTokenSymbol.value,
+ }),
+ alertType: 'error',
+ });
+ return;
+ }
+
const finalizedCallback = (result: ISubmittableResult): void => {
displayCustomMessage({
txType: TxType.dappsStaking,
diff --git a/src/i18n/en-US/index.ts b/src/i18n/en-US/index.ts
index 4923df1e9..1475636bd 100644
--- a/src/i18n/en-US/index.ts
+++ b/src/i18n/en-US/index.ts
@@ -315,6 +315,10 @@ export default {
'The amount of token to be staking must be greater than {amount} {symbol}',
allFundsWillBeTransferred:
'All funds will be transferred because the min. staking amount is {minStakingAmount} {symbol}',
+ invalidBalance:
+ 'Invalid balance to make a claim. Please add {symbol} tokens in to the account',
+ warningLeaveMinAmount:
+ 'Account must hold greater than 10{symbol} in transferrable when you stake.',
},
},
assets: {