diff --git a/biome.json b/biome.json
new file mode 100644
index 000000000..1efe951bc
--- /dev/null
+++ b/biome.json
@@ -0,0 +1,26 @@
+{
+ "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
+ "organizeImports": {
+ "enabled": true
+ },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true,
+ "suspicious": {
+ "noExplicitAny": "off"
+ },
+ "a11y": {
+ "noNoninteractiveTabindex": "off",
+ "useAnchorContent": "off"
+ }
+ }
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "space",
+ "indentWidth": 2,
+ "lineWidth": 100,
+ "ignore": ["node_modules", "dist", ".docusaurus", "static"]
+ }
+}
diff --git a/package.json b/package.json
index b619ae066..c2f3f749d 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,9 @@
"@polkadot/vue-identicon": "3.8.3",
"@quasar/app-webpack": "^3.11.2",
"@quasar/extras": "^1.16.7",
+ "@tanstack/vue-query": "5.56.2",
"@vue/apollo-composable": "^4.0.0-beta.4",
+ "@wagmi/vue": "0.0.48",
"@walletconnect/ethereum-provider": "^2.12.2",
"@walletconnect/modal": "^2.6.2",
"animate.css": "^4.1.1",
@@ -80,6 +82,7 @@
"three": "^0.165.0",
"v-odometer": "^2.0.1",
"validator": "^13.7.0",
+ "viem": "2.x",
"vue-i18n": "^9.2.2",
"vue-js-progress": "^1.0.2",
"vue-router": "^4.0.0",
diff --git a/src/components/assets/Account.vue b/src/components/assets/Account.vue
index 1e3489591..f3d09b0b7 100644
--- a/src/components/assets/Account.vue
+++ b/src/components/assets/Account.vue
@@ -144,15 +144,13 @@
diff --git a/src/components/header/modals/SelectAccount.vue b/src/components/header/modals/SelectAccount.vue
index 548fd3ec1..00c6d00ad 100644
--- a/src/components/header/modals/SelectAccount.vue
+++ b/src/components/header/modals/SelectAccount.vue
@@ -90,9 +90,8 @@ import {
truncate,
wait,
} from '@astar-network/astar-sdk-core';
-import { ApiPromise } from '@polkadot/api';
-import copy from 'copy-to-clipboard';
-import { ethers } from 'ethers';
+import type { ApiPromise } from "@polkadot/api";
+import copy from "copy-to-clipboard";
import { $api } from 'src/boot/api';
import { astarChain } from 'src/config/chain';
import { endpointKey, providerEndpoints } from 'src/config/chainEndpoints';
@@ -100,9 +99,10 @@ import { LOCAL_STORAGE } from 'src/config/localStorage';
import { SupportWallet } from 'src/config/wallets';
import { useAccount, useBreakpoints, useNetworkInfo } from 'src/hooks';
import { castMobileSource, checkIsEthereumWallet } from 'src/hooks/helper/wallet';
+import { formatEtherAsString } from "src/lib/formatters";
import { useStore } from 'src/store';
-import { SubstrateAccount } from 'src/store/general/state';
-import { PropType, computed, defineComponent, onUnmounted, ref, watch } from 'vue';
+import type { SubstrateAccount } from "src/store/general/state";
+import { type PropType, computed, defineComponent, onUnmounted, ref, watch } from "vue";
import { useI18n } from 'vue-i18n';
import Account from './Account.vue';
import UnifiedAccount from './UnifiedAccount.vue';
@@ -233,7 +233,7 @@ export default defineComponent({
if (!accountBalanceMap.value) return 0;
const account = accountBalanceMap.value.find((it) => it.address === address);
const balance = account ? account.balance : '0';
- return truncate(ethers.utils.formatEther(balance || '0'));
+ return truncate(formatEtherAsString(balance || "0"));
};
const updateAccountMap = async (): Promise => {
diff --git a/src/components/header/modals/SelectMultisigAccount.vue b/src/components/header/modals/SelectMultisigAccount.vue
index bd53942ce..717bf2460 100644
--- a/src/components/header/modals/SelectMultisigAccount.vue
+++ b/src/components/header/modals/SelectMultisigAccount.vue
@@ -138,20 +138,27 @@ import {
truncate,
wait,
} from '@astar-network/astar-sdk-core';
-import { ApiPromise } from '@polkadot/api';
-import copy from 'copy-to-clipboard';
-import { ethers } from 'ethers';
+import type { ApiPromise } from "@polkadot/api";
+import copy from "copy-to-clipboard";
import { $api } from 'src/boot/api';
import SelectSignatory from 'src/components/header/modals/SelectSignatory.vue';
import { astarChain } from 'src/config/chain';
import { providerEndpoints } from 'src/config/chainEndpoints';
import { LOCAL_STORAGE } from 'src/config/localStorage';
-import { SupportMultisig, SupportWallet } from 'src/config/wallets';
+import { SupportMultisig, type SupportWallet } from "src/config/wallets";
import { useAccount, useBreakpoints, useNetworkInfo } from 'src/hooks';
-import { MultisigAddress } from 'src/modules/multisig';
+import type { MultisigAddress } from "src/modules/multisig";
import { useStore } from 'src/store';
-import { SubstrateAccount } from 'src/store/general/state';
-import { PropType, computed, defineComponent, onUnmounted, ref, watch, watchEffect } from 'vue';
+import type { SubstrateAccount } from "src/store/general/state";
+import {
+ type PropType,
+ computed,
+ defineComponent,
+ onUnmounted,
+ ref,
+ watch,
+ watchEffect,
+} from "vue";
import { useI18n } from 'vue-i18n';
import { hasProperty, isValidAddressPolkadotAddress } from '@astar-network/astar-sdk-core';
@@ -159,12 +166,13 @@ import { web3Enable } from '@polkadot/extension-dapp';
import type { InjectedExtension } from '@polkadot/extension-inject/types';
import { encodeAddress } from '@polkadot/util-crypto';
import { useExtensions } from 'src/hooks/useExtensions';
+import { formatEtherAsString } from "src/lib/formatters";
import { polkasafeUrl } from 'src/links';
-import { Multisig, addProxyAccounts } from 'src/modules/multisig';
+import { type Multisig, addProxyAccounts } from "src/modules/multisig";
+import { PolkasafeWrapper } from "src/types/polkasafe";
import { container } from 'src/v2/common';
import { ASTAR_ADDRESS_PREFIX } from 'src/v2/repositories/implementations';
-import { Symbols } from 'src/v2/symbols';
-import { PolkasafeWrapper } from 'src/types/polkasafe';
+import { Symbols } from "src/v2/symbols";
export default defineComponent({
components: {
@@ -282,7 +290,7 @@ export default defineComponent({
onHeightChange();
const displayBalance = (balance: string): number => {
- return truncate(ethers.utils.formatEther(balance || '0'));
+ return truncate(formatEtherAsString(balance || "0"));
};
const setMultisigAccounts = async (c: PolkasafeWrapper, signatory: string): Promise => {
@@ -373,7 +381,7 @@ export default defineComponent({
const setDefaultSelectedSignatory = (): void => {
if (multisig.value) {
- substrateAccounts.value.length === 0 && useExtensions($api!!, store);
+ substrateAccounts.value.length === 0 && useExtensions($api!, store);
const account = substrateAccounts.value.find(
(it) => it.address === multisig.value!.signatory.address
);
diff --git a/src/hooks/helper/claim.ts b/src/hooks/helper/claim.ts
index ad0f35194..f6500dde0 100644
--- a/src/hooks/helper/claim.ts
+++ b/src/hooks/helper/claim.ts
@@ -1,7 +1,8 @@
-import { EventRecord } from '@polkadot/types/interfaces';
+import type { EventRecord } from "@polkadot/types/interfaces";
import { BN } from '@polkadot/util';
import { ethers } from 'ethers';
import { balanceFormatter } from 'src/hooks/helper/plasmUtils';
+import { formatEtherAsNumber } from "src/lib/formatters";
export const calculateClaimedStaker = ({
events,
@@ -22,7 +23,7 @@ export const calculateClaimedStaker = ({
}
}
});
- const claimedAmount = Number(ethers.utils.formatEther(totalClaimStaker.toString()).toString());
+ const claimedAmount = formatEtherAsNumber(totalClaimStaker);
const formattedAmount = balanceFormatter(totalClaimStaker);
return { claimedAmount, formattedAmount };
};
diff --git a/src/hooks/transfer/useTokenTransfer.ts b/src/hooks/transfer/useTokenTransfer.ts
index db7182d79..339904205 100644
--- a/src/hooks/transfer/useTokenTransfer.ts
+++ b/src/hooks/transfer/useTokenTransfer.ts
@@ -5,21 +5,22 @@ import {
isValidAddressPolkadotAddress,
isValidEvmAddress,
} from '@astar-network/astar-sdk-core';
-import { $api, $web3 } from 'boot/api';
-import { ethers } from 'ethers';
+import { $api, $web3 } from "boot/api";
import { getTokenBal } from 'src/config/web3';
import { useAccount, useBalance, useGasPrice, useNetworkInfo } from 'src/hooks';
+import { formatEtherAsNumber, formatEtherAsString } from "src/lib/formatters";
import { HistoryTxType } from 'src/modules/account';
import { addTxHistories } from 'src/modules/account/utils/index';
import { fetchXcmBalance } from 'src/modules/xcm';
import { Path } from 'src/router';
import { useStore } from 'src/store';
import { container } from 'src/v2/common';
-import { Asset } from 'src/v2/models';
-import { FrameSystemAccountInfo } from 'src/v2/repositories/implementations';
-import { IAccountUnificationService, IAssetsService } from 'src/v2/services';
+import type { Asset } from "src/v2/models";
+import type { FrameSystemAccountInfo } from "src/v2/repositories/implementations";
+import type { IAccountUnificationService, IAssetsService } from "src/v2/services";
import { Symbols } from 'src/v2/symbols';
-import { Ref, computed, ref, watch, watchEffect } from 'vue';
+import { isAddress, parseUnits } from "viem";
+import { type Ref, computed, ref, watch, watchEffect } from "vue";
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
@@ -37,8 +38,8 @@ export function useTokenTransfer(selectedToken: Ref) {
const transferableBalance = computed(() => {
const balance = accountData.value
- ? ethers.utils.formatEther(accountData.value.getUsableTransactionBalance().toString())
- : '0';
+ ? formatEtherAsString(accountData.value.getUsableTransactionBalance())
+ : "0";
return Number(balance);
});
const { selectedTip, nativeTipPrice, setSelectedTip, isEnableSpeedConfiguration } = useGasPrice();
@@ -177,7 +178,7 @@ export function useTokenTransfer(selectedToken: Ref) {
}
const decimals = Number(selectedToken.value.metadata.decimals);
- const amount = ethers.utils.parseUnits(String(transferAmt), decimals).toString();
+ const amount = parseUnits(String(transferAmt), decimals).toString();
try {
const assetsService = container.get(Symbols.AssetsService);
@@ -238,11 +239,11 @@ export function useTokenTransfer(selectedToken: Ref) {
if (isValidAddressPolkadotAddress(address)) {
const { data } = await apiRef.query.system.account(address);
const transferableBalance = data.free.sub(data.frozen);
- return Number(ethers.utils.formatEther(transferableBalance.toString()));
+ return formatEtherAsNumber(transferableBalance);
}
- if (ethers.utils.isAddress(address)) {
+ if (isAddress(address)) {
const balance = await web3Ref.eth.getBalance(address);
- return Number(ethers.utils.formatEther(balance));
+ return formatEtherAsNumber(balance);
}
return 0;
};
diff --git a/src/hooks/useEvmDeposit.ts b/src/hooks/useEvmDeposit.ts
index 29feb7a21..3b1b22907 100644
--- a/src/hooks/useEvmDeposit.ts
+++ b/src/hooks/useEvmDeposit.ts
@@ -1,10 +1,10 @@
import { buildEvmAddress } from '@astar-network/astar-sdk-core';
-import { $web3 } from 'boot/api';
-import { ethers } from 'ethers';
+import { $web3 } from "boot/api";
import { useAccount, useGasPrice } from 'src/hooks';
+import { formatEtherAsNumber } from "src/lib/formatters";
import { useStore } from 'src/store';
import { container } from 'src/v2/common';
-import { IAssetsService } from 'src/v2/services';
+import type { IAssetsService } from "src/v2/services";
import { Symbols } from 'src/v2/symbols';
import { computed, ref, watch } from 'vue';
@@ -40,8 +40,8 @@ export function useEvmDeposit() {
const h160Addr = buildEvmAddress(currentAccountRef);
const deposit = await getData(h160Addr);
evmDeposit.value = deposit;
- numEvmDeposit.value = Number(ethers.utils.formatEther(deposit.toString()));
- isEvmDeposit.value = deposit.toString() !== '0' && !isH160.value ? true : false;
+ numEvmDeposit.value = formatEtherAsNumber(deposit);
+ isEvmDeposit.value = deposit.toString() !== "0" && !isH160.value;
}
},
{ immediate: true }
diff --git a/src/hooks/useFaucet.ts b/src/hooks/useFaucet.ts
index 0382200ea..607bf9da0 100644
--- a/src/hooks/useFaucet.ts
+++ b/src/hooks/useFaucet.ts
@@ -1,12 +1,12 @@
-import { $api } from 'boot/api';
-import axios from 'axios';
-import { DateTime } from 'luxon';
-import { providerEndpoints } from 'src/config/chainEndpoints';
-import { useStore } from 'src/store';
-import { onUnmounted, ref, Ref, watch, watchEffect, computed } from 'vue';
-import { useAccount, useNetworkInfo } from 'src/hooks';
-import { ethers } from 'ethers';
-import { fetchNativeBalance } from '@astar-network/astar-sdk-core';
+import { fetchNativeBalance } from "@astar-network/astar-sdk-core";
+import axios from "axios";
+import { $api } from "boot/api";
+import { DateTime } from "luxon";
+import { providerEndpoints } from "src/config/chainEndpoints";
+import { useAccount, useNetworkInfo } from "src/hooks";
+import { formatEtherAsString } from "src/lib/formatters";
+import { useStore } from "src/store";
+import { type Ref, computed, onUnmounted, ref, watch, watchEffect } from "vue";
interface Timestamps {
lastRequestAt: number;
@@ -32,11 +32,11 @@ export function useFaucet(isModalFaucet?: Ref) {
const timestamps = ref(null);
const faucetAmount = ref(0);
const faucetBalRequirement = computed(() => faucetAmount.value / 2);
- const unit = ref('');
+ const unit = ref("");
const isAbleToFaucet = ref(false);
- const hash = ref('');
+ const hash = ref("");
const isLoading = ref(true);
- const faucetHotWalletBalance = ref('0');
+ const faucetHotWalletBalance = ref("0");
const countDown = ref({
hours: 0,
minutes: 0,
@@ -61,7 +61,7 @@ export function useFaucet(isModalFaucet?: Ref) {
const { data } = await axios.get(url);
return data;
} catch (error: any) {
- throw Error(error.message || 'Something went wrong');
+ throw Error(error.message || "Something went wrong");
} finally {
isLoading.value = false;
}
@@ -82,14 +82,14 @@ export function useFaucet(isModalFaucet?: Ref) {
const requestFaucet = async (recaptchaResponse: string): Promise => {
if (!senderSs58Account.value) {
- throw Error('Address is empty');
+ throw Error("Address is empty");
}
try {
- store.commit('general/setLoading', true);
+ store.commit("general/setLoading", true);
const endpoint = providerEndpoints[currentNetworkIdx.value].faucetEndpoint;
if (!endpoint) {
- throw Error('Cannot find the request endpoint');
+ throw Error("Cannot find the request endpoint");
}
const url = `${endpoint}/drip`;
@@ -99,20 +99,20 @@ export function useFaucet(isModalFaucet?: Ref) {
});
const msg = `Completed at block hash #${data.hash}`;
- store.dispatch('general/showAlertMsg', {
+ store.dispatch("general/showAlertMsg", {
msg,
- alertType: 'success',
+ alertType: "success",
txHash: data.hash,
});
hash.value = data.hash;
} catch (e: any) {
console.error(e);
- store.dispatch('general/showAlertMsg', {
+ store.dispatch("general/showAlertMsg", {
msg: `Transaction failed with error: ${e.message}`,
- alertType: 'error',
+ alertType: "error",
});
} finally {
- store.commit('general/setLoading', false);
+ store.commit("general/setLoading", false);
}
};
@@ -123,7 +123,7 @@ export function useFaucet(isModalFaucet?: Ref) {
if (!isAbleToFaucet.value) {
const resetTime = DateTime.fromMillis(nextRequestAt);
- const { hours, minutes, seconds } = resetTime.diffNow(['hours', 'minutes', 'seconds']);
+ const { hours, minutes, seconds } = resetTime.diffNow(["hours", "minutes", "seconds"]);
countDown.value.hours = hours;
countDown.value.minutes = minutes;
countDown.value.seconds = Number(seconds.toFixed(0));
@@ -160,9 +160,9 @@ export function useFaucet(isModalFaucet?: Ref) {
faucetAmount.value = data.faucet.amount;
unit.value = data.faucet.unit;
timestamps.value = data.timestamps;
- faucetHotWalletBalance.value = ethers.utils.formatEther(hotWalletBal);
+ faucetHotWalletBalance.value = formatEtherAsString(hotWalletBal);
},
- { immediate: false }
+ { immediate: false },
);
return {
diff --git a/src/hooks/useInflation.ts b/src/hooks/useInflation.ts
index 7010cac7b..dc96df886 100644
--- a/src/hooks/useInflation.ts
+++ b/src/hooks/useInflation.ts
@@ -1,19 +1,20 @@
-import { computed, watch, ref, Ref, ComputedRef } from 'vue';
-import { useI18n } from 'vue-i18n';
-import { useStore } from 'src/store';
-import { container } from 'src/v2/common';
-import {
+import { ethers } from "ethers";
+import { PERIOD1_START_BLOCKS } from "src/constants";
+import { formatEtherAsNumber } from "src/lib/formatters";
+import { type InflationParam, useDappStaking } from "src/staking-v3";
+import { useStore } from "src/store";
+import { container } from "src/v2/common";
+import type { InflationConfiguration } from "src/v2/models";
+import type {
BurnEvent,
IBalancesRepository,
IInflationRepository,
ITokenApiRepository,
-} from 'src/v2/repositories';
-import { Symbols } from 'src/v2/symbols';
-import { InflationConfiguration } from 'src/v2/models';
-import { InflationParam, useDappStaking } from 'src/staking-v3';
-import { ethers } from 'ethers';
-import { useNetworkInfo } from './useNetworkInfo';
-import { PERIOD1_START_BLOCKS } from 'src/constants';
+} from "src/v2/repositories";
+import { Symbols } from "src/v2/symbols";
+import { type ComputedRef, type Ref, computed, ref, watch } from "vue";
+import { useI18n } from "vue-i18n";
+import { useNetworkInfo } from "./useNetworkInfo";
type UseInflation = {
activeInflationConfiguration: ComputedRef;
@@ -39,23 +40,23 @@ export function useInflation(): UseInflation {
const realizedAdjustableStakersPart = ref(0);
const activeInflationConfiguration = computed(
- () => store.getters['general/getActiveInflationConfiguration']
+ () => store.getters["general/getActiveInflationConfiguration"],
);
const inflationParameters = computed(
- () => store.getters['general/getInflationParameters']
+ () => store.getters["general/getInflationParameters"],
);
- const currentBlock = computed(() => store.getters['general/getCurrentBlock']);
+ const currentBlock = computed(() => store.getters["general/getCurrentBlock"]);
const fetchActiveConfigurationToStore = async (): Promise => {
const inflationRepository = container.get(Symbols.InflationRepository);
const activeConfiguration = await inflationRepository.getInflationConfiguration();
- store.commit('general/setActiveInflationConfiguration', activeConfiguration);
+ store.commit("general/setActiveInflationConfiguration", activeConfiguration);
};
const fetchInflationParamsToStore = async (): Promise => {
const inflationRepository = container.get(Symbols.InflationRepository);
const params = await inflationRepository.getInflationParams();
- store.commit('general/setInflationParameters', params);
+ store.commit("general/setInflationParameters", params);
};
const getInflationParameters = async (): Promise => {
@@ -66,10 +67,10 @@ export function useInflation(): UseInflation {
const getBurnEvents = async (): Promise => {
// Ignore burn events with less than 1M ASTAR. They are not impacting charts a lot small burn amounts
// could be a spam.
- const minBurn = BigInt('1000000000000000000000000');
+ const minBurn = BigInt("1000000000000000000000000");
const tokenApiRepository = container.get(Symbols.TokenApiRepository);
const burnEvents = await tokenApiRepository.getBurnEvents(
- networkNameSubstrate.value.toLowerCase()
+ networkNameSubstrate.value.toLowerCase(),
);
return burnEvents.filter((item) => item.amount >= minBurn);
@@ -88,7 +89,7 @@ export function useInflation(): UseInflation {
if (!period1StartBlock) {
console.warn(
- t('dashboard.inflation.wrongNetwork', { network: networkNameSubstrate.value })
+ t("dashboard.inflation.wrongNetwork", { network: networkNameSubstrate.value }),
);
return;
}
@@ -102,13 +103,13 @@ export function useInflation(): UseInflation {
burnEvents.splice(0, 0, {
blockNumber: period1StartBlock,
amount: BigInt(0),
- user: '',
+ user: "",
timestamp: 0,
});
burnEvents.push({
blockNumber: currentBlock.value,
amount: BigInt(0),
- user: '',
+ user: "",
timestamp: 0,
});
@@ -133,17 +134,13 @@ export function useInflation(): UseInflation {
// Estimate total issuance at the end of the current cycle.
const endOfCycleBlock = period1StartBlock + cycleLengthInBlocks;
- const endOfCycleTotalIssuance = Number(
- ethers.utils.formatEther(
- slope * BigInt(endOfCycleBlock - period1StartBlock) + initialTotalIssuanceWithoutBurn
- )
+ const endOfCycleTotalIssuance = formatEtherAsNumber(
+ slope * BigInt(endOfCycleBlock - period1StartBlock) + initialTotalIssuanceWithoutBurn,
);
// Estimated inflation at the end of the current cycle.
inflation =
- (100 *
- (endOfCycleTotalIssuance -
- Number(ethers.utils.formatEther(initialTotalIssuanceWithoutBurn.toString())))) /
+ (100 * (endOfCycleTotalIssuance - formatEtherAsNumber(initialTotalIssuanceWithoutBurn))) /
endOfCycleTotalIssuance;
// Calculate maximum and realized inflation for each era in the cycle.
@@ -154,7 +151,7 @@ export function useInflation(): UseInflation {
cycleLengthInBlocks,
inflationParameters.value?.maxInflationRate ?? 0,
eraLengths.value.standardEraLength,
- burnEvents
+ burnEvents,
);
calculateRealizedInflationData(
@@ -163,17 +160,17 @@ export function useInflation(): UseInflation {
slope,
eraLengths.value.standardEraLength,
initialTotalIssuance,
- burnEvents
+ burnEvents,
);
calculateAdjustableStakerRewards(
realizedTotalIssuance,
currentEraInfo.value?.currentStakeAmount.totalStake ?? BigInt(0),
inflationParameters.value.adjustableStakersPart,
- inflationParameters.value.idealStakingRate
+ inflationParameters.value.idealStakingRate,
);
} catch (error) {
- console.error('Error calculating realized inflation', error);
+ console.error("Error calculating realized inflation", error);
}
estimatedInflation.value = inflation;
@@ -186,11 +183,11 @@ export function useInflation(): UseInflation {
cycleLengthInBlocks: number,
maxInflation: number,
eraLength: number,
- burnEvents: BurnEvent[]
+ burnEvents: BurnEvent[],
): void => {
const result: [number, number][] = [];
- const inflation = BigInt(Math.floor(maxInflation * 100)) * BigInt('10000000000000000');
- const cycleProgression = (firstBlockIssuance * inflation) / BigInt('1000000000000000000');
+ const inflation = BigInt(Math.floor(maxInflation * 100)) * BigInt("10000000000000000");
+ const cycleProgression = (firstBlockIssuance * inflation) / BigInt("1000000000000000000");
const cycleLength = BigInt(cycleLengthInBlocks);
// One sample per era.
@@ -205,7 +202,7 @@ export function useInflation(): UseInflation {
firstBlockIssuance -
burnEvents[j].amount;
- result.push([i, Number(ethers.utils.formatEther(inflation.toString()))]);
+ result.push([i, formatEtherAsNumber(inflation)]);
}
}
@@ -218,7 +215,7 @@ export function useInflation(): UseInflation {
slope: bigint,
eraLength: number,
firstBlockIssuance: bigint,
- burnEvents: BurnEvent[]
+ burnEvents: BurnEvent[],
): void => {
const result: [number, number][] = [];
@@ -228,10 +225,8 @@ export function useInflation(): UseInflation {
i <= burnEvents[j + 1].blockNumber + eraLength;
i += eraLength
) {
- const currentBlockIssuance = Number(
- ethers.utils.formatEther(
- slope * BigInt(i - firstBlock) + firstBlockIssuance - burnEvents[j].amount
- )
+ const currentBlockIssuance = formatEtherAsNumber(
+ slope * BigInt(i - firstBlock) + firstBlockIssuance - burnEvents[j].amount,
);
result.push([i, currentBlockIssuance]);
@@ -245,13 +240,13 @@ export function useInflation(): UseInflation {
totalIssuance: bigint,
totalStake: bigint,
adjustableStakerPart: number,
- idealStakingRate: number
+ idealStakingRate: number,
): void => {
const stakeRate =
totalStake <= BigInt(0)
? 0
- : Number(ethers.utils.formatEther(totalStake.toString())) /
- Number(ethers.utils.formatEther(totalIssuance.toString()));
+ : formatEtherAsNumber(totalStake.toString()) /
+ formatEtherAsNumber(totalIssuance.toString());
const result = adjustableStakerPart * Math.min(1, stakeRate / idealStakingRate);
realizedAdjustableStakersPart.value = Number(result.toFixed(3));
};
diff --git a/src/hooks/useTokenDistribution.ts b/src/hooks/useTokenDistribution.ts
index 7166724bf..d5b2a7aac 100644
--- a/src/hooks/useTokenDistribution.ts
+++ b/src/hooks/useTokenDistribution.ts
@@ -1,16 +1,17 @@
+import { ethers } from "ethers";
+import { formatEtherAsNumber } from "src/lib/formatters";
+import type { IDappStakingService } from "src/staking-v3";
+import { container } from "src/v2/common";
// Provides an information about tokens allocation
// Total supply, circulating supply, locked tokens, treasury tokens, etc....
-import { TvlModel } from 'src/v2/models';
-import { ref, watchEffect } from 'vue';
-import { useTokenCirculation } from './useTokenCirculation';
-import { container } from 'src/v2/common';
-import { Symbols } from 'src/v2/symbols';
-import { useBalance } from './useBalance';
-import { ethers } from 'ethers';
-import { IDappStakingService } from 'src/staking-v3';
+import type { TvlModel } from "src/v2/models";
+import { Symbols } from "src/v2/symbols";
+import { ref, watchEffect } from "vue";
+import { useBalance } from "./useBalance";
+import { useTokenCirculation } from "./useTokenCirculation";
export function useTokenDistribution() {
- const treasuryAddress = ref('YQnbw3oWxBnCUarnbePrjFcrSgVPP2jqTZYzWcccmN8fXhd');
+ const treasuryAddress = ref("YQnbw3oWxBnCUarnbePrjFcrSgVPP2jqTZYzWcccmN8fXhd");
const tvlModel = ref();
const { formatNumber, totalSupply, currentCirculating } = useTokenCirculation();
const { balance: treasuryBalance } = useBalance(treasuryAddress);
@@ -30,7 +31,7 @@ export function useTokenDistribution() {
watchEffect(() => {
if (tvlModel?.value && treasuryBalance?.value && totalSupply?.value) {
const tvlUnrounded = tvlModel?.value?.tvlDefaultUnit ?? 0;
- const treasuryUnrounded = Number(ethers.utils.formatEther(treasuryBalance.value.toString()));
+ const treasuryUnrounded = formatEtherAsNumber(treasuryBalance.value);
tvl.value = Math.round(tvlUnrounded);
treasury.value = Math.round(treasuryUnrounded);
diff --git a/src/hooks/useVesting.ts b/src/hooks/useVesting.ts
index 3434559e7..b3dcb4311 100644
--- a/src/hooks/useVesting.ts
+++ b/src/hooks/useVesting.ts
@@ -1,8 +1,9 @@
import { ethers } from 'ethers';
-import { ExtendedVestingInfo, useBalance, useGasPrice } from 'src/hooks';
+import { type ExtendedVestingInfo, useBalance, useGasPrice } from "src/hooks";
+import { formatEtherAsNumber } from "src/lib/formatters";
import { useStore } from 'src/store';
import { container } from 'src/v2/common';
-import { IAssetsService } from 'src/v2/services';
+import type { IAssetsService } from "src/v2/services";
import { Symbols } from 'src/v2/symbols';
import { computed } from 'vue';
@@ -25,16 +26,14 @@ export const useVesting = () => {
],
};
try {
- if (accountData.value && accountData.value.vesting.length) {
- const claimableAmount = Number(
- ethers.utils.formatEther(accountData.value.vestedClaimable.toString())
- );
+ if (accountData.value?.vesting.length) {
+ const claimableAmount = formatEtherAsNumber(accountData.value.vestedClaimable.toString());
const vestings = accountData.value.vesting.map((vesting: ExtendedVestingInfo) => {
const { perBlock, locked, startingBlock } = vesting.basicInfo;
- const vestedAmount = Number(ethers.utils.formatEther(vesting.vested.toString()));
- const totalDistribution = Number(ethers.utils.formatEther(locked.toString()));
- const unlockPerBlock = Number(ethers.utils.formatEther(perBlock.toString()));
+ const vestedAmount = formatEtherAsNumber(vesting.vested.toString());
+ const totalDistribution = formatEtherAsNumber(locked.toString());
+ const unlockPerBlock = formatEtherAsNumber(perBlock.toString());
const block = locked.div(perBlock).add(startingBlock);
const untilBlock = block.toNumber();
return {
diff --git a/src/hooks/wallet/useAccountUnification.ts b/src/hooks/wallet/useAccountUnification.ts
index d8505e2da..9ae3e16a7 100644
--- a/src/hooks/wallet/useAccountUnification.ts
+++ b/src/hooks/wallet/useAccountUnification.ts
@@ -1,10 +1,10 @@
import {
- ExtrinsicPayload,
+ type ExtrinsicPayload,
PayloadWithWeight,
checkSumEvmAddress,
-} from '@astar-network/astar-sdk-core';
-import { SubmittableExtrinsic } from '@polkadot/api/types';
-import { ISubmittableResult } from '@polkadot/types/types';
+} from "@astar-network/astar-sdk-core";
+import type { SubmittableExtrinsic } from "@polkadot/api/types";
+import type { ISubmittableResult } from "@polkadot/types/types";
import { BN } from '@polkadot/util';
import { $api } from 'boot/api';
import { ethers } from 'ethers';
@@ -12,25 +12,26 @@ import { get } from 'lodash-es';
import ABI from 'src/config/abi/ERC20.json';
import { setupNetwork } from 'src/config/web3';
import { useAccount } from 'src/hooks/useAccount';
+import { formatEtherAsString } from "src/lib/formatters";
import { getEvmExplorerUrl } from 'src/links';
+import { getRawEvmTransaction } from "src/modules/evm";
import { evmPrecompiledContract } from 'src/modules/precompiled';
import { AlertMsg } from 'src/modules/toast';
+import { useDappStaking, useDapps } from "src/staking-v3";
import { useStore } from 'src/store';
-import { XcmAssets } from 'src/store/assets/state';
+import type { XcmAssets } from "src/store/assets/state";
+import type { UnifiedAccount } from "src/store/general/state";
import { container } from 'src/v2/common';
-import { ExtrinsicStatusMessage, IEventAggregator } from 'src/v2/messaging';
-import { Asset } from 'src/v2/models';
-import { IAccountUnificationService, IIdentityService } from 'src/v2/services';
+import { ExtrinsicStatusMessage, type IEventAggregator } from "src/v2/messaging";
+import type { Asset } from "src/v2/models";
+import type { IAccountUnificationRepository, IIdentityRepository } from "src/v2/repositories";
+import type { IAccountUnificationService, IIdentityService } from "src/v2/services";
import { Symbols } from 'src/v2/symbols';
-import { WatchCallback, computed, ref, watch } from 'vue';
+import { type WatchCallback, computed, ref, watch } from "vue";
import { useI18n } from 'vue-i18n';
import Web3 from 'web3';
-import { AbiItem } from 'web3-utils';
-import { useNetworkInfo } from '../useNetworkInfo';
-import { IAccountUnificationRepository, IIdentityRepository } from 'src/v2/repositories';
-import { UnifiedAccount } from 'src/store/general/state';
-import { getRawEvmTransaction } from 'src/modules/evm';
-import { useDappStaking, useDapps } from 'src/staking-v3';
+import type { AbiItem } from "web3-utils";
+import { useNetworkInfo } from "../useNetworkInfo";
const provider = get(window, 'ethereum') as any;
@@ -117,7 +118,7 @@ export const useAccountUnification = () => {
if (!selectedEvmAddress.value || !protocolState.value || !ledger.value) return;
try {
- let isPendingWithdrawal =
+ const isPendingWithdrawal =
rewards.value.bonus > BigInt(0) ||
rewards.value.dApp > BigInt(0) ||
rewards.value.staker.amount > BigInt(0);
@@ -311,7 +312,7 @@ export const useAccountUnification = () => {
]);
const totalDeposit = depositInfo.basic + depositInfo.field * BigInt(TOTAL_FIELDS) + mappingFee;
- return `${ethers.utils.formatEther(totalDeposit.toString())} ${nativeTokenSymbol.value}`;
+ return `${formatEtherAsString(totalDeposit)} ${nativeTokenSymbol.value}`;
};
watch([web3], updateEvmProvider);
diff --git a/src/hooks/xcm/useTransferRouter.ts b/src/hooks/xcm/useTransferRouter.ts
index 9fdee4e65..b60077901 100644
--- a/src/hooks/xcm/useTransferRouter.ts
+++ b/src/hooks/xcm/useTransferRouter.ts
@@ -1,30 +1,31 @@
-import { Erc20Token } from 'src/modules/token';
-import { providerEndpoints } from 'src/config/chainEndpoints';
-import { ethers } from 'ethers';
-import { endpointKey } from 'src/config/chainEndpoints';
-import { useAccount, useBalance, useNetworkInfo } from 'src/hooks';
+import { capitalize } from "@astar-network/astar-sdk-core";
+import { ethers } from "ethers";
+import { providerEndpoints } from "src/config/chainEndpoints";
+import { endpointKey } from "src/config/chainEndpoints";
+import { useAccount, useBalance, useNetworkInfo } from "src/hooks";
+import { formatEtherAsNumber } from "src/lib/formatters";
+import { productionOrigin } from "src/links";
+import type { Erc20Token } from "src/modules/token";
import {
checkIsSupportAstarNativeToken,
removeEvmName,
restrictedXcmNetwork,
xcmChains,
xcmToken,
-} from 'src/modules/xcm';
-import { Chain, XcmChain } from 'src/v2/models/XcmModels';
-import { generateAssetFromEvmToken, generateNativeAsset } from 'src/modules/xcm/tokens';
-import { useStore } from 'src/store';
-import { Asset, astarChains } from 'src/v2/models';
-import { computed, ref, watch, watchEffect } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
-import { EvmAssets, XcmAssets } from 'src/store/assets/state';
-import { capitalize } from '@astar-network/astar-sdk-core';
-import { Path } from 'src/router';
-import { productionOrigin } from 'src/links';
-
-export const pathEvm = '-evm';
-export type TransferMode = 'local' | 'xcm';
-export const astarNetworks = ['astar', 'shiden', 'shibuya'];
-export const astarNativeTokens = ['sdn', 'astr', 'sby'];
+} from "src/modules/xcm";
+import { generateAssetFromEvmToken, generateNativeAsset } from "src/modules/xcm/tokens";
+import { Path } from "src/router";
+import { useStore } from "src/store";
+import type { EvmAssets, XcmAssets } from "src/store/assets/state";
+import { type Asset, astarChains } from "src/v2/models";
+import { Chain, type XcmChain } from "src/v2/models/XcmModels";
+import { computed, ref, watch, watchEffect } from "vue";
+import { useRoute, useRouter } from "vue-router";
+
+export const pathEvm = "-evm";
+export type TransferMode = "local" | "xcm";
+export const astarNetworks = ["astar", "shiden", "shibuya"];
+export const astarNativeTokens = ["sdn", "astr", "sby"];
const disabledXcmChains: endpointKey[] = [];
export interface NetworkFromTo {
@@ -47,16 +48,16 @@ export function useTransferRouter() {
const mode = computed(() => route.query.mode as TransferMode);
const from = computed(() => route.query.from as string);
const to = computed(() => route.query.to as string);
- const isTransferPage = computed(() => route.fullPath.includes('transfer'));
+ const isTransferPage = computed(() => route.fullPath.includes("transfer"));
const isEvmBridge = computed(() => {
if (!isTransferPage.value || isLocalTransfer.value) return false;
return to.value.includes(pathEvm);
});
const { nativeTokenSymbol, currentNetworkName, currentNetworkIdx, currentNetworkChain, isZkEvm } =
useNetworkInfo();
- const isH160 = computed(() => store.getters['general/isH160Formatted']);
- const xcmAssets = computed(() => store.getters['assets/getAllAssets']);
- const evmAssets = computed(() => store.getters['assets/getEvmAllAssets']);
+ const isH160 = computed(() => store.getters["general/isH160Formatted"]);
+ const xcmAssets = computed(() => store.getters["assets/getAllAssets"]);
+ const evmAssets = computed(() => store.getters["assets/getEvmAllAssets"]);
const xcmOpponentChain = computed(() => {
const chain = astarChains.includes(capitalize(from.value) as Chain) ? to.value : from.value;
return capitalize(chain) as Chain;
@@ -67,20 +68,20 @@ export function useTransferRouter() {
if (restrictedNetworksArray.length === 0) return [];
return restrictedNetworksArray
.filter(({ isRestrictedFromEvm, isRestrictedFromNative }) =>
- isH160.value ? isRestrictedFromEvm : isRestrictedFromNative
+ isH160.value ? isRestrictedFromEvm : isRestrictedFromNative,
)
.map(({ chain }) => chain);
});
const setNativeTokenBalance = (): void => {
- nativeTokenBalance.value = Number(ethers.utils.formatEther(useableBalance.value));
+ nativeTokenBalance.value = formatEtherAsNumber(useableBalance.value);
};
const redirect = (): void => {
const token = nativeTokenSymbol.value.toLowerCase();
router.push({
path: `/${network.value}/assets/transfer`,
- query: { token, mode: 'local' },
+ query: { token, mode: "local" },
});
};
@@ -198,7 +199,7 @@ export function useTransferRouter() {
originChain: string;
}): void => {
isLocalTransfer.value = isLocal;
- const mode = isLocal ? 'local' : 'xcm';
+ const mode = isLocal ? "local" : "xcm";
const isNativeAstarToken = tokenSymbol.value === nativeTokenSymbol.value.toLowerCase();
const opponentNetwork = isNativeAstarToken
@@ -218,7 +219,7 @@ export function useTransferRouter() {
};
const setToken = (t: Asset): void => {
- const mode = isLocalTransfer.value ? 'local' : 'xcm';
+ const mode = isLocalTransfer.value ? "local" : "xcm";
const token = t.metadata.symbol.toLowerCase();
const baseQuery = { token, mode };
const xcmQuery = {
@@ -256,7 +257,7 @@ export function useTransferRouter() {
const token = isAstarEvm ? tokenSymbol.value : t.toLowerCase();
router.replace({
path: `/${network.value}/assets/transfer`,
- query: { ...route.query, token, from, to, mode: 'xcm' },
+ query: { ...route.query, token, from, to, mode: "xcm" },
});
};
@@ -288,7 +289,7 @@ export function useTransferRouter() {
if (!xcmAssets.value || !nativeTokenSymbol.value) return [];
selectableTokens = xcmAssets.value.assets;
tokens = selectableTokens.filter(
- ({ isXcmCompatible, userBalance }) => isXcmCompatible || userBalance
+ ({ isXcmCompatible, userBalance }) => isXcmCompatible || userBalance,
);
tokens.push(nativeTokenAsset);
}
@@ -301,14 +302,14 @@ export function useTransferRouter() {
const isSupportAstarNativeToken = checkIsSupportAstarNativeToken(selectedNetwork);
if (isH160.value) {
const filteredToken = evmTokens.map((it) =>
- generateAssetFromEvmToken(it as Erc20Token, xcmAssets.value.assets)
+ generateAssetFromEvmToken(it as Erc20Token, xcmAssets.value.assets),
);
selectableTokens = filteredToken
.filter(({ isXcmCompatible }) => isXcmCompatible)
.filter((it) => it.originChain === selectedNetwork);
} else {
selectableTokens = xcmAssets.value.assets.filter(
- (it) => it.originChain === selectedNetwork
+ (it) => it.originChain === selectedNetwork,
);
}
tokens = selectableTokens.filter(({ isXcmCompatible }) => isXcmCompatible);
@@ -326,7 +327,7 @@ export function useTransferRouter() {
}
const isCustomNetwork = network.value === providerEndpoints[endpointKey.CUSTOM].networkAlias;
- isLocalTransfer.value = mode.value === 'local';
+ isLocalTransfer.value = mode.value === "local";
const isRedirect =
!isCustomNetwork &&
!isZkEvm.value &&
@@ -339,7 +340,7 @@ export function useTransferRouter() {
const nativeTokenAsset = { ...nativeToken, userBalance: nativeBal };
token.value = nativeTokenAsset;
token.value = tokens.value.find(
- (it) => it.metadata.symbol.toLowerCase() === tokenSymbol.value.toLowerCase()
+ (it) => it.metadata.symbol.toLowerCase() === tokenSymbol.value.toLowerCase(),
);
};
@@ -357,7 +358,7 @@ export function useTransferRouter() {
const isFetchedXcmAssets = xcmAssets.value.assets.length > 0;
if (isFetchedXcmAssets && tokenSymbol.value) {
const isFound = tokens.value.find(
- (it) => it.metadata.symbol.toLowerCase() === tokenSymbol.value.toLowerCase()
+ (it) => it.metadata.symbol.toLowerCase() === tokenSymbol.value.toLowerCase(),
);
!isFound && redirect();
}
@@ -377,7 +378,7 @@ export function useTransferRouter() {
const isDisabledXcmChain = disabledXcmChains.some((it) => it === currentNetworkIdx.value);
- const originChain = token.value?.originChain || '';
+ const originChain = token.value?.originChain || "";
return checkIsDisabledToken(originChain) || isDisabledXcmChain;
});
@@ -390,7 +391,7 @@ export function useTransferRouter() {
// Memo: redirect to the assets page if users access to the XCM transfer page by inputting URL directly
const handleDisableXcmTransfer = (): void => {
- if (checkIsDisabledXcmChain(from.value, to.value) && mode.value === 'xcm') {
+ if (checkIsDisabledXcmChain(from.value, to.value) && mode.value === "xcm") {
router.push(Path.Assets);
}
};
diff --git a/src/hooks/xvm/useXvmTokenTransfer.ts b/src/hooks/xvm/useXvmTokenTransfer.ts
index c3553bef0..ab7849dab 100644
--- a/src/hooks/xvm/useXvmTokenTransfer.ts
+++ b/src/hooks/xvm/useXvmTokenTransfer.ts
@@ -1,33 +1,33 @@
-import { ethers } from 'ethers';
-import { getTokenBal } from 'src/config/web3';
-import { useBalance, useGasPrice, useNetworkInfo } from 'src/hooks';
import {
ASTAR_SS58_FORMAT,
+ SUBSTRATE_SS58_FORMAT,
buildEvmAddress,
isValidAddressPolkadotAddress,
isValidEvmAddress,
- SUBSTRATE_SS58_FORMAT,
-} from '@astar-network/astar-sdk-core';
-import { useAccount } from 'src/hooks/useAccount';
-import { Erc20Token } from 'src/modules/token';
-import { Path } from 'src/router';
-import { useStore } from 'src/store';
-import { container } from 'src/v2/common';
-import { IXvmService } from 'src/v2/services/IXvmService';
-import { Symbols } from 'src/v2/symbols';
-import { computed, ref, Ref, watch, watchEffect } from 'vue';
-import { useI18n } from 'vue-i18n';
-import { useRoute, useRouter } from 'vue-router';
-
-type ContractType = 'wasm-erc20' | 'wasm-psp22';
+} from "@astar-network/astar-sdk-core";
+import { getTokenBal } from "src/config/web3";
+import { useBalance, useGasPrice, useNetworkInfo } from "src/hooks";
+import { useAccount } from "src/hooks/useAccount";
+import { formatEtherAsString } from "src/lib/formatters";
+import type { Erc20Token } from "src/modules/token";
+import { Path } from "src/router";
+import { useStore } from "src/store";
+import { container } from "src/v2/common";
+import type { IXvmService } from "src/v2/services/IXvmService";
+import { Symbols } from "src/v2/symbols";
+import { type Ref, computed, ref, watch, watchEffect } from "vue";
+import { useI18n } from "vue-i18n";
+import { useRoute, useRouter } from "vue-router";
+
+type ContractType = "wasm-erc20" | "wasm-psp22";
export function useXvmTokenTransfer(selectedToken: Ref) {
const transferAmt = ref(null);
const toAddressBalance = ref(0);
- const toAddress = ref('');
- const errMsg = ref('');
+ const toAddress = ref("");
+ const errMsg = ref("");
const isChecked = ref(false);
- const xvmContract = ref('wasm-erc20');
+ const xvmContract = ref("wasm-erc20");
const { t } = useI18n();
const store = useStore();
@@ -37,18 +37,18 @@ export function useXvmTokenTransfer(selectedToken: Ref) {
const router = useRouter();
const { accountData } = useBalance(currentAccount);
const { evmNetworkIdx, nativeTokenSymbol } = useNetworkInfo();
- const isH160 = computed(() => store.getters['general/isH160Formatted']);
+ const isH160 = computed(() => store.getters["general/isH160Formatted"]);
const tokenSymbol = computed(() => route.query.token as string);
- const isLoading = computed(() => store.getters['general/isLoading']);
+ const isLoading = computed(() => store.getters["general/isLoading"]);
const isRequiredCheck = computed(() => true);
const fromAddressBalance = computed(() =>
- selectedToken.value ? Number(selectedToken.value.userBalance) : 0
+ selectedToken.value ? Number(selectedToken.value.userBalance) : 0,
);
const transferableBalance = computed(() => {
const balance = accountData.value
- ? ethers.utils.formatEther(accountData.value.getUsableTransactionBalance().toString())
- : '0';
+ ? formatEtherAsString(accountData.value.getUsableTransactionBalance())
+ : "0";
return Number(balance);
});
@@ -57,7 +57,7 @@ export function useXvmTokenTransfer(selectedToken: Ref) {
0 >= Number(transferAmt.value) || fromAddressBalance.value < Number(transferAmt.value);
const noAddress = !toAddress.value;
return (
- errMsg.value !== '' ||
+ errMsg.value !== "" ||
isLessAmount ||
noAddress ||
(isRequiredCheck.value && !isChecked.value)
@@ -74,13 +74,13 @@ export function useXvmTokenTransfer(selectedToken: Ref) {
const inputHandler = (event: any): void => {
transferAmt.value = event.target.value;
- errMsg.value = '';
+ errMsg.value = "";
};
const resetStates = (): void => {
- transferAmt.value = '';
- toAddress.value = '';
- errMsg.value = '';
+ transferAmt.value = "";
+ toAddress.value = "";
+ errMsg.value = "";
isChecked.value = false;
toAddressBalance.value = 0;
};
@@ -98,17 +98,17 @@ export function useXvmTokenTransfer(selectedToken: Ref) {
const transferAmtRef = Number(transferAmt.value);
try {
if (transferAmtRef > fromAddressBalance.value) {
- errMsg.value = t('warning.insufficientBalance', {
+ errMsg.value = t("warning.insufficientBalance", {
token: selectedToken.value.symbol,
});
} else if (toAddress.value && !isValidDestAddress.value) {
- errMsg.value = 'warning.inputtedInvalidDestAddress';
+ errMsg.value = "warning.inputtedInvalidDestAddress";
} else if (!transferableBalance.value) {
- errMsg.value = t('warning.insufficientBalance', {
+ errMsg.value = t("warning.insufficientBalance", {
token: nativeTokenSymbol.value,
});
} else {
- errMsg.value = '';
+ errMsg.value = "";
}
} catch (error: any) {
errMsg.value = error.message;
@@ -118,7 +118,7 @@ export function useXvmTokenTransfer(selectedToken: Ref) {
const setXvmContract = (): void => {
if (!toAddress.value) return;
const isSendToH160 = isValidEvmAddress(toAddress.value);
- xvmContract.value = isSendToH160 ? 'wasm-erc20' : 'wasm-psp22';
+ xvmContract.value = isSendToH160 ? "wasm-erc20" : "wasm-psp22";
};
const setToAddressBalance = async (): Promise => {
@@ -158,11 +158,11 @@ export function useXvmTokenTransfer(selectedToken: Ref) {
});
} catch (e: any) {
console.error(e);
- store.dispatch('general/showAlertMsg', {
- msg: e.message || 'Something went wrong during asset transfer.',
- alertType: 'error',
+ store.dispatch("general/showAlertMsg", {
+ msg: e.message || "Something went wrong during asset transfer.",
+ alertType: "error",
});
- store.commit('general/setLoading', false);
+ store.commit("general/setLoading", false);
}
};
diff --git a/src/hooks/xvm/useXvmTransferRouter.ts b/src/hooks/xvm/useXvmTransferRouter.ts
index 0727ba932..09476fa5a 100644
--- a/src/hooks/xvm/useXvmTransferRouter.ts
+++ b/src/hooks/xvm/useXvmTransferRouter.ts
@@ -1,6 +1,7 @@
import { ethers } from 'ethers';
import { useAccount, useBalance } from 'src/hooks';
-import { Erc20Token } from 'src/modules/token';
+import { formatEtherAsNumber } from "src/lib/formatters";
+import type { Erc20Token } from "src/modules/token";
import { useStore } from 'src/store';
import { computed, ref, watchEffect } from 'vue';
import { useRoute, useRouter } from 'vue-router';
@@ -34,7 +35,7 @@ export function useXvmTransferRouter() {
});
const setNativeTokenBalance = (): void => {
- nativeTokenBalance.value = Number(ethers.utils.formatEther(useableBalance.value));
+ nativeTokenBalance.value = formatEtherAsNumber(useableBalance.value);
};
const redirect = (): void => {
diff --git a/src/lib/formatters.ts b/src/lib/formatters.ts
new file mode 100644
index 000000000..5fa5aa7db
--- /dev/null
+++ b/src/lib/formatters.ts
@@ -0,0 +1,30 @@
+
+import { BN } from "@polkadot/util";
+import { formatEther } from "viem";
+
+export function formatEtherAsString(wei: bigint | string | BN): string {
+ let weiBigInt: bigint;
+
+ if (typeof wei === "bigint") {
+ weiBigInt = wei;
+ } else if (typeof wei === "string") {
+ weiBigInt = BigInt(wei);
+ } else if (wei instanceof BN) {
+ weiBigInt = BigInt(wei.toString());
+ } else {
+ throw new Error("Invalid input type");
+ }
+
+ return formatEther(weiBigInt);
+}
+
+export function formatEtherAsNumber(wei: bigint | string | BN): number {
+ const etherBigInt = BigInt(formatEtherAsString(wei));
+ const MAX_SAFE_INTEGER_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
+
+ if (etherBigInt > MAX_SAFE_INTEGER_BIGINT || etherBigInt < -MAX_SAFE_INTEGER_BIGINT) {
+ throw new Error("Value is outside of safe integer bounds for JavaScript numbers");
+ }
+
+ return Number(etherBigInt);
+}
diff --git a/src/modules/information/recent-history/stake/index.ts b/src/modules/information/recent-history/stake/index.ts
index 8a2d967f0..17149568b 100644
--- a/src/modules/information/recent-history/stake/index.ts
+++ b/src/modules/information/recent-history/stake/index.ts
@@ -1,8 +1,8 @@
import { TOKEN_API_URL } from '@astar-network/astar-sdk-core';
import axios from 'axios';
-import { ethers } from 'ethers';
-import { DappCombinedInfo } from 'src/v2/models';
-import { RecentHistory, RecentHistoryTxType } from './../../index';
+import { formatEtherAsString } from "src/lib/formatters";
+import type { DappCombinedInfo } from "src/v2/models";
+import type { RecentHistory, RecentHistoryTxType } from "./../../index";
interface UserStakeHistory {
timestamp: string;
@@ -63,7 +63,7 @@ export const getStakeTxHistories = async ({
const note = dapp && dapp.dapp ? dapp.dapp.name : '';
const explorerUrl = subScan + '/extrinsic/' + it.transactionHash;
return {
- amount: ethers.utils.formatEther(it.amount),
+ amount: formatEtherAsString(it.amount),
timestamp: String(Number(it.timestamp) / 1000),
txType: it.transaction as RecentHistoryTxType,
explorerUrl,
diff --git a/src/staking-v3/components/my-staking/ModalUnbondDapp.vue b/src/staking-v3/components/my-staking/ModalUnbondDapp.vue
index 1379db174..0b990a4c4 100644
--- a/src/staking-v3/components/my-staking/ModalUnbondDapp.vue
+++ b/src/staking-v3/components/my-staking/ModalUnbondDapp.vue
@@ -69,19 +69,20 @@