fix: Move BigInt formatting functions from helper.ts to kraiken-lib/format (#246)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-02-24 23:00:58 +00:00
parent 0f74cc8276
commit 8c43d3890c
16 changed files with 377 additions and 102 deletions

View file

@ -1,16 +1,17 @@
{
"name": "kraiken-lib",
"version": "0.2.0",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "kraiken-lib",
"version": "0.2.0",
"version": "1.0.0",
"dependencies": {
"@apollo/client": "^3.9.10",
"graphql": "^16.8.1",
"graphql-tag": "^2.12.6"
"graphql-tag": "^2.12.6",
"viem": "^2.22.13"
},
"devDependencies": {
"@graphql-codegen/cli": "^5.0.2",
@ -31,6 +32,12 @@
"typescript": "^5.4.3"
}
},
"node_modules/@adraffy/ens-normalize": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz",
"integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==",
"license": "MIT"
},
"node_modules/@ampproject/remapping": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@ -219,6 +226,7 @@
"integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.24.2",
@ -2865,6 +2873,45 @@
"dev": true,
"license": "MIT"
},
"node_modules/@noble/ciphers": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz",
"integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==",
"license": "MIT",
"engines": {
"node": "^14.21.3 || >=16"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@noble/curves": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz",
"integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==",
"license": "MIT",
"dependencies": {
"@noble/hashes": "1.8.0"
},
"engines": {
"node": "^14.21.3 || >=16"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@noble/hashes": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
"license": "MIT",
"engines": {
"node": "^14.21.3 || >=16"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -2952,6 +2999,42 @@
"dev": true,
"license": "MIT"
},
"node_modules/@scure/base": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz",
"integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==",
"license": "MIT",
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@scure/bip32": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz",
"integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==",
"license": "MIT",
"dependencies": {
"@noble/curves": "~1.9.0",
"@noble/hashes": "~1.8.0",
"@scure/base": "~1.2.5"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@scure/bip39": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz",
"integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==",
"license": "MIT",
"dependencies": {
"@noble/hashes": "~1.8.0",
"@scure/base": "~1.2.5"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@sinclair/typebox": {
"version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
@ -3106,6 +3189,7 @@
"integrity": "sha512-F1CBxgqwOMc4GKJ7eY22hWhBVQuMYTtqI8L0FcszYcpYX0fzfDGpez22Xau8Mgm7O9fI+zA/TYIdq3tGWfweBA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.13.0"
}
@ -3190,6 +3274,7 @@
"integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.45.0",
"@typescript-eslint/types": "8.45.0",
@ -3511,12 +3596,34 @@
"node": ">=8"
}
},
"node_modules/abitype": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz",
"integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/wevm"
},
"peerDependencies": {
"typescript": ">=5.0.4",
"zod": "^3.22.0 || ^4.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"node_modules/acorn": {
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -3939,6 +4046,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001587",
"electron-to-chromium": "^1.4.668",
@ -4775,6 +4883,7 @@
"integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@ -5043,7 +5152,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
"dev": true,
"license": "MIT"
},
"node_modules/execa": {
@ -5515,6 +5623,7 @@
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz",
"integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==",
"license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
@ -5599,6 +5708,7 @@
"integrity": "sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==",
"devOptional": true,
"license": "MIT",
"peer": true,
"workspaces": [
"website"
],
@ -6145,6 +6255,21 @@
"ws": "*"
}
},
"node_modules/isows": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz",
"integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/wevm"
}
],
"license": "MIT",
"peerDependencies": {
"ws": "*"
}
},
"node_modules/istanbul-lib-coverage": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
@ -6258,6 +6383,7 @@
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jest/core": "^29.7.0",
"@jest/types": "^29.6.3",
@ -7929,6 +8055,36 @@
"node": ">=0.10.0"
}
},
"node_modules/ox": {
"version": "0.12.4",
"resolved": "https://registry.npmjs.org/ox/-/ox-0.12.4.tgz",
"integrity": "sha512-+P+C7QzuwPV8lu79dOwjBKfB2CbnbEXe/hfyyrff1drrO1nOOj3Hc87svHfcW1yneRr3WXaKr6nz11nq+/DF9Q==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/wevm"
}
],
"license": "MIT",
"dependencies": {
"@adraffy/ens-normalize": "^1.11.0",
"@noble/ciphers": "^1.3.0",
"@noble/curves": "1.9.1",
"@noble/hashes": "^1.8.0",
"@scure/bip32": "^1.7.0",
"@scure/bip39": "^1.6.0",
"abitype": "^1.2.3",
"eventemitter3": "5.0.1"
},
"peerDependencies": {
"typescript": ">=5.4.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@ -9238,8 +9394,9 @@
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
"dev": true,
"devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -9425,6 +9582,36 @@
"node": ">=12"
}
},
"node_modules/viem": {
"version": "2.46.3",
"resolved": "https://registry.npmjs.org/viem/-/viem-2.46.3.tgz",
"integrity": "sha512-2LJS+Hyh2sYjHXQtzfv1kU9pZx9dxFzvoU/ZKIcn0FNtOU0HQuIICuYdWtUDFHaGXbAdVo8J1eCvmjkL9JVGwg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/wevm"
}
],
"license": "MIT",
"dependencies": {
"@noble/curves": "1.9.1",
"@noble/hashes": "1.8.0",
"@scure/bip32": "1.7.0",
"@scure/bip39": "1.6.0",
"abitype": "1.2.3",
"isows": "1.0.7",
"ox": "0.12.4",
"ws": "8.18.3"
},
"peerDependencies": {
"typescript": ">=5.0.4"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
@ -9557,11 +9744,11 @@
}
},
"node_modules/ws": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
"dev": true,
"version": "8.18.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10.0.0"
},

View file

@ -50,6 +50,11 @@
"types": "./dist/position.d.ts",
"require": "./dist/position.js",
"import": "./dist/position.js"
},
"./format": {
"types": "./dist/format.d.ts",
"require": "./dist/format.js",
"import": "./dist/format.js"
}
},
"files": [
@ -74,7 +79,8 @@
"dependencies": {
"@apollo/client": "^3.9.10",
"graphql": "^16.8.1",
"graphql-tag": "^2.12.6"
"graphql-tag": "^2.12.6",
"viem": "^2.22.13"
},
"devDependencies": {
"@graphql-codegen/cli": "^5.0.2",

26
kraiken-lib/src/format.ts Normal file
View file

@ -0,0 +1,26 @@
import { formatUnits } from 'viem';
/** Convert wei (bigint or string) to a JS number. Core primitive. */
export function weiToNumber(value: bigint | string, decimals = 18): number {
const bi = typeof value === 'string' ? BigInt(value || '0') : (value ?? 0n);
return Number(formatUnits(bi, decimals));
}
/** Format wei to fixed decimal string (e.g. "0.00123") */
export function formatWei(value: bigint | string, decimals = 18, digits = 5): string {
const num = weiToNumber(value, decimals);
return num === 0 ? '0' : num.toFixed(digits);
}
/** Format number to compact display (e.g. "1.23K", "4.56M") */
export function compactNumber(value: number): string {
return Intl.NumberFormat('en-US', {
notation: 'compact',
maximumFractionDigits: 2,
}).format(value);
}
/** Format number with commas (e.g. "1,234,567") */
export function commaNumber(value: number): string {
return value ? value.toLocaleString('en-US') : '0';
}

View file

@ -0,0 +1,112 @@
import { describe, expect, test } from '@jest/globals';
import { weiToNumber, formatWei, compactNumber, commaNumber } from '../format.js';
describe('weiToNumber', () => {
test('returns 0 for zero bigint', () => {
expect(weiToNumber(0n)).toBe(0);
});
test('returns 0 for empty string', () => {
expect(weiToNumber('')).toBe(0);
});
test('converts 1 ether bigint to 1', () => {
expect(weiToNumber(1_000_000_000_000_000_000n)).toBe(1);
});
test('converts string wei to number', () => {
expect(weiToNumber('1000000000000000000')).toBe(1);
});
test('handles small values correctly', () => {
expect(weiToNumber(1n)).toBeCloseTo(1e-18);
});
test('handles large values', () => {
expect(weiToNumber(1_000_000_000_000_000_000_000n)).toBe(1000);
});
test('respects custom decimals', () => {
expect(weiToNumber(1_000_000n, 6)).toBe(1);
});
test('handles string with custom decimals', () => {
expect(weiToNumber('1000000', 6)).toBe(1);
});
});
describe('formatWei', () => {
test('returns "0" for zero bigint', () => {
expect(formatWei(0n)).toBe('0');
});
test('returns "0" for zero string', () => {
expect(formatWei('0')).toBe('0');
});
test('formats 1 ether with default 5 digits', () => {
expect(formatWei(1_000_000_000_000_000_000n)).toBe('1.00000');
});
test('formats with custom digits', () => {
expect(formatWei(1_000_000_000_000_000_000n, 18, 2)).toBe('1.00');
});
test('formats small value', () => {
const result = formatWei(1_230_000_000_000_000n, 18, 5);
expect(result).toBe('0.00123');
});
test('formats string input', () => {
expect(formatWei('2000000000000000000', 18, 4)).toBe('2.0000');
});
test('formats large values', () => {
const wei = 1_000_000n * 10n ** 18n;
expect(formatWei(wei, 18, 2)).toBe('1000000.00');
});
});
describe('compactNumber', () => {
test('formats thousands', () => {
expect(compactNumber(1234)).toBe('1.23K');
});
test('formats millions', () => {
expect(compactNumber(4_560_000)).toBe('4.56M');
});
test('formats zero', () => {
expect(compactNumber(0)).toBe('0');
});
test('formats small number without suffix', () => {
expect(compactNumber(123)).toBe('123');
});
test('formats billions', () => {
expect(compactNumber(1_000_000_000)).toBe('1B');
});
});
describe('commaNumber', () => {
test('returns "0" for falsy input', () => {
expect(commaNumber(0)).toBe('0');
});
test('formats thousands with commas', () => {
expect(commaNumber(1234)).toBe('1,234');
});
test('formats millions with commas', () => {
expect(commaNumber(1_234_567)).toBe('1,234,567');
});
test('formats small number without commas', () => {
expect(commaNumber(99)).toBe('99');
});
test('formats negative number', () => {
expect(commaNumber(-1234)).toBe('-1,234');
});
});

View file

@ -18,7 +18,7 @@
<div class="notification-bell__event-details">
<div class="notification-bell__event-title">Position snatched</div>
<div class="notification-bell__event-meta">
<span>{{ formatTokenAmount(event.tokenAmount, 18, 2) }} $KRK</span>
<span>{{ formatWei(event.tokenAmount, 18, 2) }} $KRK</span>
<span class="notification-bell__event-time">{{ relativeTime(event.timestamp) }}</span>
</div>
</div>
@ -35,7 +35,8 @@ import { Icon } from '@iconify/vue';
import { useSnatchNotifications } from '@/composables/useSnatchNotifications';
import { useWallet } from '@/composables/useWallet';
import { DEFAULT_CHAIN_ID } from '@/config';
import { relativeTime, formatTokenAmount } from '@/utils/helper';
import { formatWei } from 'kraiken-lib/format';
import { relativeTime } from '@/utils/helper';
const wallet = useWallet();
const chainId = wallet.account.chainId ?? DEFAULT_CHAIN_ID;

View file

@ -205,7 +205,7 @@ import FInput from '@/components/fcomponents/FInput.vue';
import FLoader from '@/components/fcomponents/FLoader.vue';
import IconInfo from '@/components/icons/IconInfo.vue';
import { Icon } from '@iconify/vue';
import { bigInt2Number } from '@/utils/helper';
import { weiToNumber } from 'kraiken-lib/format';
import { loadPositions, usePositions, type Position } from '@/composables/usePositions';
import { useStake } from '@/composables/useStake';
import { useClaim } from '@/composables/useClaim';
@ -258,8 +258,8 @@ watchEffect(() => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(async () => {
stake.stakingAmountShares = await assetsToShares(stake.stakingAmount);
const stakingAmountSharesNumber = bigInt2Number(stake.stakingAmountShares, 18);
const stakeableSupplyNumber = bigInt2Number(statCollection.stakeableSupply, 18);
const stakingAmountSharesNumber = weiToNumber(stake.stakingAmountShares, 18);
const stakeableSupplyNumber = weiToNumber(statCollection.stakeableSupply, 18);
if (stakeableSupplyNumber === 0) {
supplyFreeze.value = 0;
@ -275,11 +275,11 @@ watchEffect(() => {
stakeSlots.value = Number.isFinite(slots) ? slots.toFixed(2) : '0.00';
});
const minStakeAmount = computed(() => bigInt2Number(minStake.value, 18));
const minStakeAmount = computed(() => weiToNumber(minStake.value, 18));
const maxStakeAmount = computed(() => {
if (wallet.balance?.value) {
return bigInt2Number(wallet.balance.value, 18);
return weiToNumber(wallet.balance.value, 18);
}
return 0;
});

View file

@ -4,7 +4,7 @@
<script setup lang="ts">
import ChartJs from '@/components/chart/ChartJs.vue';
import { bigInt2Number, formatBigIntDivision } from '@/utils/helper';
import { weiToNumber } from 'kraiken-lib/format';
import { computed, ref } from 'vue';
import { useStatCollection } from '@/composables/useStatCollection';
import { useStake } from '@/composables/useStake';
@ -21,23 +21,23 @@ const stake = useStake();
const statCollection = useStatCollection(initialChainId);
const minStake = computed(() => statCollection.minStake ?? 0n);
const minStakeAmount = computed(() => {
return formatBigIntDivision(minStake.value, 10n ** 18n);
return weiToNumber(minStake.value, 18);
});
const ignoreOwner = ref(false);
const taxRate = ref<number>(1.0);
const snatchPositions = computed(() => {
if (
bigInt2Number(statCollection.outstandingStake, 18) + stake.stakingAmountNumber <=
bigInt2Number(statCollection.kraikenTotalSupply, 18) * 0.2
weiToNumber(statCollection.outstandingStake, 18) + stake.stakingAmountNumber <=
weiToNumber(statCollection.kraikenTotalSupply, 18) * 0.2
) {
return [];
}
//Differenz aus outstandingSupply und totalSupply bestimmen, wie viel HARB kann zum Snatch verwendet werden
const difference =
bigInt2Number(statCollection.outstandingStake, 18) +
weiToNumber(statCollection.outstandingStake, 18) +
stake.stakingAmountNumber -
bigInt2Number(statCollection.kraikenTotalSupply, 18) * 0.2;
weiToNumber(statCollection.kraikenTotalSupply, 18) * 0.2;
//Division ohne Rest, um zu schauen wie viele Positionen gesnatched werden könnten
const snatchAblePositionsCount = Math.floor(difference / minStakeAmount.value);

View file

@ -84,7 +84,7 @@ import FButton from '@/components/fcomponents/FButton.vue';
import FTag from '@/components/fcomponents/FTag.vue';
import FSelect from '@/components/fcomponents/FSelect.vue';
import FCollapse from '@/components/fcomponents/FCollapse.vue';
import { compactNumber, formatBigNumber } from '@/utils/helper';
import { compactNumber, formatWei } from 'kraiken-lib/format';
import { useUnstake } from '@/composables/useUnstake';
import { useAdjustTaxRate } from '@/composables/useAdjustTaxRates';
import { computed, ref, onMounted } from 'vue';
@ -216,7 +216,7 @@ async function unstakePosition() {
async function loadActivePositionData() {
//loadTaxDue
taxDue.value = await getTaxDue(props.id);
taxPaidGes.value = formatBigNumber(taxDue.value + BigInt(props.position.taxPaid), 18);
taxPaidGes.value = formatWei(taxDue.value + BigInt(props.position.taxPaid), 18);
//loadTotalSupply

View file

@ -45,7 +45,8 @@ import type { Position } from '@/composables/usePositions';
import FCollapse from '@/components/fcomponents/FCollapse.vue';
import FTag from '@/components/fcomponents/FTag.vue';
import { RouterLink } from 'vue-router';
import { compactNumber, relativeTime, formatTokenAmount } from '@/utils/helper';
import { compactNumber, formatWei } from 'kraiken-lib/format';
import { relativeTime } from '@/utils/helper';
import { calculateClosedPositionProfit } from 'kraiken-lib/position';
import { computed } from 'vue';
@ -69,7 +70,7 @@ const profit = computed(() => {
const payoutKrk = computed(() => {
if (!props.position.payout) return null;
return formatTokenAmount(props.position.payout);
return formatWei(props.position.payout, 18, 4);
});
const relativeClosedAt = computed(() => {

View file

@ -56,7 +56,8 @@
<script setup lang="ts">
import { getCurrentInstance, computed } from 'vue';
import { useRouter } from 'vue-router';
import { getAddressShortName, compactNumber, formatBigIntDivision } from '@/utils/helper';
import { compactNumber, weiToNumber } from 'kraiken-lib/format';
import { getAddressShortName } from '@/utils/helper';
import { getBlocky } from '@/utils/blockies';
import FButton from '@/components/fcomponents/FButton.vue';
import FOutput from '@/components/fcomponents/FOutput.vue';
@ -89,7 +90,7 @@ function loadConnectorImage(connector: Connector) {
const harbAmount = computed(() => {
if (wallet.balance?.value) {
return compactNumber(formatBigIntDivision(wallet.balance?.value, 10n ** BigInt(wallet.balance.decimals)));
return compactNumber(weiToNumber(wallet.balance?.value, wallet.balance.decimals));
} else {
return '0';
}

View file

@ -5,7 +5,7 @@ import axios from 'axios';
import { getAccount, watchChainId, watchAccount, watchContractEvent, type Config } from '@wagmi/core';
import type { WatchChainIdReturnType, WatchAccountReturnType, GetAccountReturnType } from '@wagmi/core';
import { bigInt2Number } from '@/utils/helper';
import { weiToNumber } from 'kraiken-lib/format';
import { getTaxRateIndexByDecimal } from '@/composables/useAdjustTaxRates';
import logger from '@/utils/logger';
import { DEFAULT_CHAIN_ID } from '@/config';
@ -43,7 +43,7 @@ const activePositions = computed(() => {
return {
...obj,
positionId: BigInt(obj.id),
amount: bigInt2Number(obj.harbDeposit, 18),
amount: weiToNumber(obj.harbDeposit, 18),
taxRatePercentage: taxRateDecimal * 100,
taxRate: taxRateDecimal,
taxRateIndex,
@ -97,7 +97,7 @@ const myClosedPositions: ComputedRef<Position[]> = computed(() => {
...obj,
positionId: BigInt(obj.id),
amount: obj.share * 1000000,
// amount: bigInt2Number(obj.harbDeposit, 18),
// amount: weiToNumber(obj.harbDeposit, 18),
taxRatePercentage: taxRateDecimal * 100,
taxRate: taxRateDecimal,
taxRateIndex,

View file

@ -8,7 +8,7 @@ import { StakeContract, permitAndSnatch, minStake } from '@/contracts/stake';
import { getNonce, nonce, getName } from '@/contracts/harb';
import { useWallet } from '@/composables/useWallet';
import { createPermitObject, getSignatureRSV } from '@/utils/blockchain';
import { formatBigIntDivision, compactNumber } from '@/utils/helper';
import { weiToNumber, compactNumber } from 'kraiken-lib/format';
import { getTaxRateOptionByIndex } from '@/composables/useAdjustTaxRates';
import { useContractToast } from './useContractToast';
const wallet = useWallet();
@ -69,7 +69,7 @@ export function useStake() {
const stakingAmountNumber = computed({
// getter
get() {
return formatBigIntDivision(stakingAmount.value, 10n ** 18n);
return weiToNumber(stakingAmount.value, 18);
},
// setter
set(newValue) {
@ -128,8 +128,7 @@ export function useStake() {
}) as DecodeEventLogReturnType & { args: PositionCreatedArgs };
const eventArgs: PositionCreatedArgs = topics.args;
const decimalsAsBigInt = typeof wallet.balance.decimals === 'bigint' ? wallet.balance.decimals : BigInt(wallet.balance.decimals);
const amount = compactNumber(formatBigIntDivision(eventArgs.harbergDeposit, 10n ** decimalsAsBigInt));
const amount = compactNumber(weiToNumber(eventArgs.harbergDeposit, wallet.balance.decimals));
contractToast.showSuccessToast(amount, 'Success!', 'You Staked', 'Check your positions on the<br /> Staker Dashboard', '$KRK');
waiting.value = false;

View file

@ -5,7 +5,7 @@ import type { Config } from '@wagmi/core';
import { config } from '@/wagmi';
import logger from '@/utils/logger';
import type { WatchBlocksReturnType } from 'viem';
import { bigInt2Number } from '@/utils/helper';
import { weiToNumber } from 'kraiken-lib/format';
import { minStake as stakeMinStake } from '@/contracts/stake';
import { DEFAULT_CHAIN_ID } from '@/config';
import { createRetryManager, formatGraphqlError, resolveGraphqlEndpoint } from '@/utils/graphqlRetry';
@ -174,7 +174,7 @@ const stakeableSupply = computed(() => {
//maxSlots
const maxSlots = computed(() => {
if (rawStatsCollections.value?.length > 0 && BigInt(rawStatsCollections.value[0].kraikenTotalSupply) > 0n) {
return (bigInt2Number(stakeTotalSupply.value, 18) * 0.2) / 100;
return (weiToNumber(stakeTotalSupply.value, 18) * 0.2) / 100;
} else {
return 0;
}
@ -182,8 +182,8 @@ const maxSlots = computed(() => {
const claimedSlots = computed(() => {
if (stakeTotalSupply.value > 0n) {
const stakeableSupplyNumber = bigInt2Number(stakeableSupply.value, 18);
const outstandingStakeNumber = bigInt2Number(outstandingStake.value, 18);
const stakeableSupplyNumber = weiToNumber(stakeableSupply.value, 18);
const outstandingStakeNumber = weiToNumber(outstandingStake.value, 18);
return (outstandingStakeNumber / stakeableSupplyNumber) * maxSlots.value;
} else {
return 0;

View file

@ -4,7 +4,7 @@ import { waitForTransactionReceipt } from '@wagmi/core';
import type { Config } from '@wagmi/core';
import { config } from '@/wagmi';
import { useContractToast } from './useContractToast';
import { compactNumber, formatBigIntDivision } from '@/utils/helper';
import { compactNumber, weiToNumber } from 'kraiken-lib/format';
import { decodeEventLog, type DecodeEventLogReturnType } from 'viem';
import { useWallet } from './useWallet';
@ -55,7 +55,7 @@ export function useUnstake() {
const eventArgs: PositionRemovedArgs = topics.args;
const amount = compactNumber(formatBigIntDivision(eventArgs.harbergPayout, 10n ** BigInt(wallet.balance.decimals)));
const amount = compactNumber(weiToNumber(eventArgs.harbergPayout, wallet.balance.decimals));
contractToast.showSuccessToast(amount, 'Success!', 'You unstaked', '', '$KRK');
waiting.value = false;

View file

@ -9,43 +9,6 @@ export function getAddressShortName(address: string) {
return addressBegin + '...' + addressEnd;
}
export function compactNumber(number: number) {
return Intl.NumberFormat('en-US', {
notation: 'compact',
// minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(number);
}
export function formatBigNumber(number: bigint, decimals: number, digits: number = 5) {
let bigIntNumber = number;
if (!bigIntNumber) {
bigIntNumber = BigInt(0);
}
const formattedNumber = Number(formatUnits(bigIntNumber, decimals));
if (formattedNumber === 0) {
return '0';
}
return formattedNumber.toFixed(digits);
}
export function bigInt2Number(number: bigint, decimals: number) {
let bigIntNumber = number;
if (!bigIntNumber) {
bigIntNumber = BigInt(0);
}
const formattedNumber = Number(formatUnits(bigIntNumber, decimals));
return formattedNumber;
}
export function InsertCommaNumber(number: number) {
if (!number) {
return 0;
}
const formattedWithOptions = number.toLocaleString('en-US');
return formattedWithOptions;
}
export function relativeTime(timestamp: string | number): string {
try {
const sec = typeof timestamp === 'string' ? Number(timestamp) : timestamp;
@ -60,14 +23,6 @@ export function relativeTime(timestamp: string | number): string {
}
}
export function formatTokenAmount(raw: string, decimals: number = 18, digits: number = 4): string {
try {
return Number(formatUnits(BigInt(raw), decimals)).toFixed(digits);
} catch {
return '?';
}
}
export function parseTokenAmount(rawWei: string, decimals = 18): number {
try {
return Number(formatUnits(BigInt(rawWei), decimals));
@ -75,16 +30,3 @@ export function parseTokenAmount(rawWei: string, decimals = 18): number {
return 0;
}
}
export function formatBigIntDivision(nominator: bigint, denominator: bigint, _digits: number = 2) {
if (!nominator) {
return 0;
}
const display = nominator.toString();
const decimal = (Number(denominator) / 10).toString().length;
const [integer, fraction] = [display.slice(0, display.length - decimal), display.slice(display.length - decimal)];
// output type number
return Number(integer + '.' + fraction);
}

View file

@ -62,7 +62,7 @@
<StatsOutput headline="Average Slot Tax" :price="`${averageTaxRate.toFixed(2)} %`"></StatsOutput>
<StatsOutput
headline="Claimed Owner Slots"
:price="`${InsertCommaNumber(stats.claimedSlots)} / ${InsertCommaNumber(stats.maxSlots)}`"
:price="`${commaNumber(stats.claimedSlots)} / ${commaNumber(stats.maxSlots)}`"
></StatsOutput>
<StatsOutput headline="Total Supply Change / 7d" :price="`+ ${stats.totalSupplyChange7d} $KRK`"></StatsOutput>
<StatsOutput headline="Inflation / 7d" :price="`+${stats.inflation7d}%`"></StatsOutput>
@ -129,7 +129,7 @@ import { usePositions } from '@/composables/usePositions';
const { status } = useAccount();
const showPanel = inject('showPanel');
import { InsertCommaNumber } from '@/utils/helper';
import { commaNumber } from 'kraiken-lib/format';
const wallet = useWallet();
const initialChainId = wallet.account.chainId ?? DEFAULT_CHAIN_ID;
const { myActivePositions, myClosedPositions, tresholdValue, activePositions } = usePositions(initialChainId);