diff --git a/web-app/src/composables/usePositionDashboard.ts b/web-app/src/composables/usePositionDashboard.ts index e26751e..2846d67 100644 --- a/web-app/src/composables/usePositionDashboard.ts +++ b/web-app/src/composables/usePositionDashboard.ts @@ -2,6 +2,7 @@ import { ref, computed, onMounted, onUnmounted, type Ref } from 'vue'; import axios from 'axios'; import { DEFAULT_CHAIN_ID } from '@/config'; import { resolveGraphqlEndpoint, formatGraphqlError } from '@/utils/graphqlRetry'; +import { parseTokenAmount } from '@/utils/helper'; import logger from '@/utils/logger'; const GRAPHQL_TIMEOUT_MS = 15_000; @@ -39,16 +40,6 @@ export interface ActivePositionShort { kraikenDeposit: string; } -function formatTokenAmount(rawWei: string, decimals = 18): number { - try { - const big = BigInt(rawWei); - const divisor = 10 ** decimals; - return Number(big) / divisor; - } catch { - return 0; - } -} - function formatDate(ts: string | null): string { if (!ts) return 'N/A'; try { @@ -178,13 +169,13 @@ export function usePositionDashboard(positionId: Ref) { } // Derived values - const depositKrk = computed(() => formatTokenAmount(position.value?.kraikenDeposit ?? '0')); - const taxPaidKrk = computed(() => formatTokenAmount(position.value?.taxPaid ?? '0')); + const depositKrk = computed(() => parseTokenAmount(position.value?.kraikenDeposit ?? '0')); + const taxPaidKrk = computed(() => parseTokenAmount(position.value?.taxPaid ?? '0')); const currentValueKrk = computed(() => { if (!position.value || !stats.value) return 0; const share = Number(position.value.share); - const outstanding = formatTokenAmount(stats.value.outstandingStake); + const outstanding = parseTokenAmount(stats.value.outstandingStake); return share * outstanding; }); @@ -245,7 +236,7 @@ export function usePositionDashboard(positionId: Ref) { return { count: lower, level, color }; }); - const payoutKrk = computed(() => formatTokenAmount(position.value?.payout ?? '0')); + const payoutKrk = computed(() => parseTokenAmount(position.value?.payout ?? '0')); const netPnlKrk = computed(() => { if (!position.value) return 0; diff --git a/web-app/src/composables/useWalletDashboard.ts b/web-app/src/composables/useWalletDashboard.ts index d48a941..b455466 100644 --- a/web-app/src/composables/useWalletDashboard.ts +++ b/web-app/src/composables/useWalletDashboard.ts @@ -2,6 +2,7 @@ import { ref, computed, onMounted, onUnmounted, type Ref } from 'vue'; import axios from 'axios'; import { DEFAULT_CHAIN_ID } from '@/config'; import { resolveGraphqlEndpoint, formatGraphqlError } from '@/utils/graphqlRetry'; +import { parseTokenAmount } from '@/utils/helper'; import logger from '@/utils/logger'; const GRAPHQL_TIMEOUT_MS = 15_000; @@ -36,16 +37,6 @@ export interface WalletStats { holderCount: number; } -function formatTokenAmount(rawWei: string, decimals = 18): number { - try { - const big = BigInt(rawWei); - const divisor = 10 ** decimals; - return Number(big) / divisor; - } catch { - return 0; - } -} - export function useWalletDashboard(address: Ref) { const holderBalance = ref('0'); const holderTotalEthSpent = ref('0'); @@ -145,13 +136,13 @@ export function useWalletDashboard(address: Ref) { } // Derived values - const balanceKrk = computed(() => formatTokenAmount(holderBalance.value)); + const balanceKrk = computed(() => parseTokenAmount(holderBalance.value)); const ethBacking = computed(() => { if (!stats.value) return 0; const balance = balanceKrk.value; - const reserve = formatTokenAmount(stats.value.lastEthReserve); - const totalSupply = formatTokenAmount(stats.value.kraikenTotalSupply); + const reserve = parseTokenAmount(stats.value.lastEthReserve); + const totalSupply = parseTokenAmount(stats.value.kraikenTotalSupply); if (totalSupply === 0) return 0; return balance * (reserve / totalSupply); }); @@ -160,21 +151,21 @@ export function useWalletDashboard(address: Ref) { if (!stats.value) return 0; const balance = balanceKrk.value; // floorPriceWei is price per token in wei → convert to ETH - const floorPriceEth = formatTokenAmount(stats.value.floorPriceWei); + const floorPriceEth = parseTokenAmount(stats.value.floorPriceWei); return balance * floorPriceEth; }); // Cost basis & P&L const avgCostBasis = computed(() => { - const spent = formatTokenAmount(holderTotalEthSpent.value); - const acquired = formatTokenAmount(holderTotalTokensAcquired.value); + const spent = parseTokenAmount(holderTotalEthSpent.value); + const acquired = parseTokenAmount(holderTotalTokensAcquired.value); if (acquired === 0) return 0; return spent / acquired; }); const currentPriceEth = computed(() => { if (!stats.value?.currentPriceWei) return 0; - return formatTokenAmount(stats.value.currentPriceWei); + return parseTokenAmount(stats.value.currentPriceWei); }); const unrealizedPnlEth = computed(() => { diff --git a/web-app/src/utils/helper.ts b/web-app/src/utils/helper.ts index 50cc08a..607ad89 100644 --- a/web-app/src/utils/helper.ts +++ b/web-app/src/utils/helper.ts @@ -68,6 +68,14 @@ export function formatTokenAmount(raw: string, decimals: number = 18, digits: nu } } +export function parseTokenAmount(rawWei: string, decimals = 18): number { + try { + return Number(formatUnits(BigInt(rawWei), decimals)); + } catch { + return 0; + } +} + export function formatBigIntDivision(nominator: bigint, denominator: bigint, _digits: number = 2) { if (!nominator) { return 0;