diff --git a/public/images/dapp_promotions/Archisinal.png b/public/images/dapp_promotions/Archisinal.png new file mode 100644 index 000000000..2907fb88d Binary files /dev/null and b/public/images/dapp_promotions/Archisinal.png differ diff --git a/src/App.vue b/src/App.vue index f2f6b8e7c..28b6673e9 100644 --- a/src/App.vue +++ b/src/App.vue @@ -28,12 +28,6 @@ - - store.getters['general/isLoading']); const showAlert = computed(() => store.getters['general/showAlert']); const isEthWallet = computed(() => store.getters['general/isEthWallet']); @@ -124,18 +115,6 @@ export default defineComponent({ showDisclaimerModal.value = isOpen; }; - // Yoki Origins modal - const showYokiOriginsModal = ref(false); - if (!localStorage.getItem(LOCAL_STORAGE.CLOSE_YOKI_ORIGINS_MODAL)) { - setTimeout(() => { - showYokiOriginsModal.value = true; - }, 2000); - } - - const setYokiOriginsModal = (isOpen: boolean): void => { - showYokiOriginsModal.value = isOpen; - }; - // Handle busy and extrinsic call status messages. const eventAggregator = container.get(Symbols.EventAggregator); eventAggregator.subscribe(ExtrinsicStatusMessage.name, (m) => { @@ -186,6 +165,7 @@ export default defineComponent({ fetchStakerInfoToStore(), fetchEraLengthsToStore(), fetchActiveConfigurationToStore(), + fetchInflationParamsToStore(), ]); } }); @@ -235,8 +215,6 @@ export default defineComponent({ isLoading, showAlert, showDisclaimerModal, - showYokiOriginsModal, - setYokiOriginsModal, setShowDisclaimerModal, }; }, diff --git a/src/assets/img/yoki-origins-background.png b/src/assets/img/yoki-origins-background.png deleted file mode 100644 index 1c6b20741..000000000 Binary files a/src/assets/img/yoki-origins-background.png and /dev/null differ diff --git a/src/assets/img/yoki-origins-logo.png b/src/assets/img/yoki-origins-logo.png deleted file mode 100644 index bc22e31d7..000000000 Binary files a/src/assets/img/yoki-origins-logo.png and /dev/null differ diff --git a/src/components/common/ChartPanel.vue b/src/components/common/ChartPanel.vue index f75ae337e..0150d908d 100644 --- a/src/components/common/ChartPanel.vue +++ b/src/components/common/ChartPanel.vue @@ -3,7 +3,7 @@
-
+
{{ $t(title) }}
@@ -95,7 +95,7 @@ export default defineComponent({ setup(props, { emit }) { const store = useStore(); const isDarkTheme = computed(() => store.getters['general/theme'] === 'DARK'); - const getBackgroundColor = (): string => (isDarkTheme.value ? '#060b23' : '#fff'); + const getBackgroundColor = (): string => 'transparent'; const getLineColor = (): string => (isDarkTheme.value ? 'rgba(108,111,111,0.1)' : '#F7F7F8'); const getTextColor = (): string => (isDarkTheme.value ? '#5F656F' : '#B1B7C1'); const hasData = ref(false); diff --git a/src/components/common/DoughnutChart.vue b/src/components/common/DoughnutChart.vue index 1ce95df72..a11f2f500 100644 --- a/src/components/common/DoughnutChart.vue +++ b/src/components/common/DoughnutChart.vue @@ -23,14 +23,14 @@ :fill="textColor" :x="size * 0.55" :y="size * 0.55 - 28" - font-size="24" + font-size="20" font-weight="700" text-anchor="middle" > {{ text }} - - - -
- {{ $t('modals.yokiOrigins.introducing') }} -
-
- -
- - - -
- - {{ $t('modals.yokiOrigins.learnMore') }} - - - {{ $t('modals.yokiOrigins.keep') }} - -
-
- - - - - - - diff --git a/src/components/common/styles/chart-panel.scss b/src/components/common/styles/chart-panel.scss index 0ef1df2b2..32beb0117 100644 --- a/src/components/common/styles/chart-panel.scss +++ b/src/components/common/styles/chart-panel.scss @@ -1,18 +1,5 @@ @import 'src/css/quasar.variables.scss'; -.container--chart { - box-shadow: $container-border-shadow-light; - background: $container-bg-white; - border-radius: 6px; - padding: 8px 16px; - @media (min-width: $md) { - padding: 8px 24px; - } - @media (min-width: $xxl) { - width: 560px; - } -} - .row { padding: 16px 8px 0px 8px; } @@ -74,10 +61,3 @@ font-size: 26px; } } - -.body--dark { - .container--chart { - box-shadow: $container-border-shadow-dark; - background-color: $container-bg-dark; - } -} diff --git a/src/components/dashboard/BlockPanel.vue b/src/components/dashboard/BlockPanel.vue index 58272eb44..e1d2761a1 100644 --- a/src/components/dashboard/BlockPanel.vue +++ b/src/components/dashboard/BlockPanel.vue @@ -2,114 +2,91 @@
-
-
- {{ $t('dashboard.block.block') }} -
- -
-
-
-
-
- {{ $t('dashboard.block.blockHeight') }} -
-
- -
-
+
+
+
+
+ {{ $t('dashboard.block.blockHeight') }}
- -
-
-
-
- {{ $t('dashboard.block.blockTime') }} -
- - +
+ +
+
+
+
+
+
+ {{ $t('dashboard.block.blockTime') }} +
+ + +
-
- {{ $t('dashboard.block.avgBlockTime') }} -
-
-
-
- {{ $t('dashboard.block.oneEra') }} - {{ $n(avgBlockTime1Era) }} -
-
- {{ $t('dashboard.block.sevenEras') }} - {{ $n(avgBlockTime7Eras) }} -
-
- {{ - $t('dashboard.block.thirtyEras') - }} - {{ $n(avgBlockTime30Eras) }} -
+ {{ $t('dashboard.block.avgBlockTime') }} +
+
+
+
+ {{ $t('dashboard.block.oneEra') }} + {{ $n(avgBlockTime1Era) }} +
+
+ {{ $t('dashboard.block.sevenEras') }} + {{ $n(avgBlockTime7Eras) }} +
+
+ {{ $t('dashboard.block.thirtyEras') }} + {{ $n(avgBlockTime30Eras) }}
- -
+
+
-
- - {{ $n(Number(avgBlockTime1Era)) }} - - {{ $t('dashboard.block.secs') }} -
+
+
+ + {{ $n(Number(avgBlockTime1Era)) }} + + {{ $t('dashboard.block.secs') }}
- -
-
- {{ $t('dashboard.block.era') }} +
+
+
+ {{ $t('dashboard.block.era') }} +
+
+ +
+
+
+ + {{ progress }}% +
-
-
- - {{ $n(era) }} - -
-
-
- -
-
- - {{ $n(blocksUntilNextEra) }} - -
-
-
-
- - {{ $t('dashboard.block.progress', { value: progress }) }} - - - {{ $t('dashboard.block.eta', { value: etaNextEra }) }} - -
-
-
- - {{ $n(era + 1) }} - -
+
+ {{ $t('dashboard.block.eta', { value: etaNextEra }) }}
@@ -117,20 +94,22 @@ + + diff --git a/src/components/dashboard/InflationRateChart.vue b/src/components/dashboard/InflationRateChart.vue new file mode 100644 index 000000000..79c855e0f --- /dev/null +++ b/src/components/dashboard/InflationRateChart.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/src/components/dashboard/NetworkStatus.vue b/src/components/dashboard/NetworkStatus.vue index d5c7a64a2..0e6d9b665 100644 --- a/src/components/dashboard/NetworkStatus.vue +++ b/src/components/dashboard/NetworkStatus.vue @@ -3,11 +3,9 @@
-
-
- - {{ $t('dashboard.network.networkStatuses') }} - +
+
+ {{ $t('dashboard.network.networkStatuses') }}
@@ -77,9 +75,9 @@
-
-
  • {{ item }}
  • -
    +
    +
    +
  • {{ item }}
  • @@ -243,5 +241,6 @@ export default defineComponent({ diff --git a/src/components/dashboard/styles/block-panel.scss b/src/components/dashboard/styles/block-panel.scss index 6f16ced16..ce7eead6f 100644 --- a/src/components/dashboard/styles/block-panel.scss +++ b/src/components/dashboard/styles/block-panel.scss @@ -1,62 +1,22 @@ @import 'src/css/quasar.variables.scss'; -.row { - padding: 16px 8px 0px 8px; - margin-bottom: 16px; - @media (min-width: $md) { - margin-bottom: 24px; - padding-left: 16px; - } -} - -.container--block-information { - display: flex; - flex-direction: column; - align-items: center; - padding-right: 16px; - padding-left: 16px; - row-gap: 24px; - @media (min-width: $md) { - display: grid; - grid-template-columns: 50% 50%; - padding-right: 16px; - padding-left: 16px; - } -} - -.container__box-stats { - display: flex; - flex-direction: column; - align-items: center; - row-gap: 24px; - @media (min-width: $md) { - flex-direction: row; - column-gap: 40px; - } -} - .skeleton--chart { height: 368px; @media (min-width: $md) { - height: 160px; + height: 298px; } } .container--block { width: 100%; - padding: 8px 16px 32px; - height: 368px; - @media (min-width: $md) { - height: 160px; - } -} - -.column-block { display: flex; flex-direction: column; - align-items: center; + gap: 16px; + @media (min-width: $md) { - align-items: flex-start; + flex-direction: row; + gap: 32px; + height: 298px; } } @@ -64,6 +24,7 @@ margin-bottom: 8px; display: flex; flex-direction: column; + @media (min-width: $md) { align-items: flex-start; } @@ -74,98 +35,16 @@ column-gap: 8px; } -.block__column--era { - display: flex; - justify-content: space-between; - justify-items: center; - padding-left: 36px; - padding-right: 36px; - align-items: baseline; - @media (min-width: $md) { - padding: 0; - } -} - -.column--bar { - align-items: center; - display: grid; - min-width: 210px; - row-gap: 16px; - padding: 0 8px; - - @media (min-width: $md) { - width: 80%; - } - @media (min-width: $xl) { - min-width: 256px; - } -} - -.bar__bottom { - display: flex; - align-items: baseline; - justify-content: space-between; -} - -.bar__top { - position: relative; -} - -.q-linear-progress { - color: $astar-blue; -} - -.row--block-next-era { - position: absolute; - width: 100%; - font-weight: 500; - bottom: -3px; - font-size: 12px; -} - -.column--block-next-era { - display: flex; - justify-content: center; -} - .box--block-information { display: flex; + flex: 1; flex-direction: column; - width: 350px; - @media (min-width: $md) { - width: 100%; - } } .box--era-information { display: flex; + flex: 1; flex-direction: column; - width: 350px; - align-items: center; - @media (min-width: $md) { - align-items: flex-start; - width: 310px; - justify-self: end; - flex-direction: row; - column-gap: 36px; - } - @media (min-width: $lg) { - width: auto; - max-width: 350px; - justify-self: auto; - padding-left: 10%; - } - @media (min-width: $xl) { - column-gap: 72px; - } - @media (min-width: $xxl) { - padding-left: 56px; - column-gap: 72px; - } -} - -.container--title--color { - color: #b1b7c1; } .box--avg-time { @@ -195,8 +74,43 @@ font-weight: 500; } +.value-panel { + flex: 1; + border-radius: 6px; + padding: 24px; + box-shadow: $container-border-shadow-light; +} + +.left-panel { + display: flex; + flex-direction: column; + flex: 1; + gap: 16px; + + @media (min-width: $md) { + gap: 32px; + } +} + +.era-chart { + display: flex; + justify-content: center; + align-items: center; + margin: 8px 0; +} + +.eta { + text-align: right; + margin-top: 32px; +} + .body--dark { .q-linear-progress { color: $astar-blue-dark; } + + .value-panel { + background: $navy-2; + box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.10); + } } diff --git a/src/components/dashboard/styles/common.scss b/src/components/dashboard/styles/common.scss new file mode 100644 index 000000000..5c903fd1f --- /dev/null +++ b/src/components/dashboard/styles/common.scss @@ -0,0 +1,18 @@ +@import 'src/css/quasar.variables.scss'; + +.container--component { + width: 100%; + padding: 16px; + border-radius: 16px; + box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.1); + background: $white; + + @media (min-width: $md) { + padding: 48px; + } +} + +.container--title--large { + font-size: 32px; + font-weight: 900; +} diff --git a/src/components/dashboard/styles/dashboard.scss b/src/components/dashboard/styles/dashboard.scss index 0af7c4d5b..a4668e7c4 100644 --- a/src/components/dashboard/styles/dashboard.scss +++ b/src/components/dashboard/styles/dashboard.scss @@ -47,12 +47,18 @@ width: 100%; row-gap: 24px; column-gap: 32px; + margin-bottom: 16px; + @media (min-width: $xxl) { display: grid; grid-template-columns: 1fr 1fr; - width: 1152px; row-gap: 32px; - margin-bottom: 16px; + + > * { + box-sizing: border-box; + overflow: hidden; + word-wrap: break-word; + } } } @@ -198,18 +204,48 @@ margin-top: 2px; } +.tokenomics { + display: flex; + flex-direction: column; + gap: 16px; + margin-top: 32px; + + @media (min-width: $md) { + gap: 32px; + flex-direction: row; + } +} + +.tokenomics-panel { + display: flex; + flex-direction: column; + flex: 1; + gap: 16px; + + @media (min-width: $md) { + gap: 32px; + } +} + .body--dark { .filter--tabs { - border: 1px solid $gray-5-selected-dark; + border: 1px solid $navy-3; div:not(:last-child) { - border-right: 1px solid $gray-5; + border-right: 1px solid $navy-3; } .selected { - background-color: $gray-5-selected-dark; + background-color: $navy-3; } } + + .container--component { + border: 2px solid $navy-3; + background: rgba(8, 16, 41, 0.50); + box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.40); + backdrop-filter: blur(3px); + } } .row-gap { diff --git a/src/components/dashboard/styles/network-status.scss b/src/components/dashboard/styles/network-status.scss index 72a9199d8..6500ef313 100644 --- a/src/components/dashboard/styles/network-status.scss +++ b/src/components/dashboard/styles/network-status.scss @@ -5,40 +5,37 @@ } .skeleton--value-panel { - height: 514px; + height: 305px; + width: 100%; &.is-zk-evm { height: 151px !important; } } -.container--value { - padding: 8px 16px 32px; - - @media (min-width: $sm) { - padding: 8px 24px 32px; - } - @media (min-width: $xxl) { - width: 560px; - } -} - .container--title--color { - color: #b1b7c1; -} - -.row--title { - padding: 16px 8px 0px 8px; + color: $white; } .box--statuses { + display: flex; + flex-direction: column; padding: 40px 8px 0px 8px; + gap: 16px; } .row--network-statuses { display: flex; flex-direction: column; row-gap: 16px; + + @media (min-width: $md) { + display: grid; + grid-template-rows: repeat(4, 1fr); + grid-auto-flow: column; + column-gap: 32px; + row-gap: 16px; + } } .row--network { @@ -66,6 +63,11 @@ li { color: $warning-yellow; } + + @media (min-width: $md) { + width: calc(50% - 8px); + margin-left: auto; + } } .column--status { diff --git a/src/components/header/YokiBanner.vue b/src/components/header/YokiBanner.vue deleted file mode 100644 index ac104f56d..000000000 --- a/src/components/header/YokiBanner.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - - - diff --git a/src/config/localStorage.ts b/src/config/localStorage.ts index 270e0396c..2d1c07d29 100644 --- a/src/config/localStorage.ts +++ b/src/config/localStorage.ts @@ -21,7 +21,6 @@ export enum LOCAL_STORAGE { IS_LEDGER = 'isLedger', MULTISIG = 'multisig', CLOSE_DAPP_STAKING_V3_ONBOARDING = 'closeDappStakingV3Onboarding', - CLOSE_YOKI_ORIGINS_MODAL = 'closeYokiOriginsModal', DECOMMISSION = 'decommission', } diff --git a/src/data/dapp_promotions.json b/src/data/dapp_promotions.json index 08679701d..07da0b670 100644 --- a/src/data/dapp_promotions.json +++ b/src/data/dapp_promotions.json @@ -46,5 +46,11 @@ "shortDescription": "#1 Cross-chain Social Fitness App on iOS & Android, Apple Watch", "link": "https://app.moonfit.xyz/astar-reward", "img": "images/dapp_promotions/moonfit.png" + }, + { + "name": "Archisinal", + "shortDescription": "Pioneering Real-World-Assets in the built environment", + "link": "https://www.archisinal.io/", + "img": "images/dapp_promotions/Archisinal.png" } ] diff --git a/src/hooks/useInflation.ts b/src/hooks/useInflation.ts index 34fb683ad..9eb0de11d 100644 --- a/src/hooks/useInflation.ts +++ b/src/hooks/useInflation.ts @@ -1,31 +1,60 @@ -import { computed, watch, ref } from 'vue'; +import { computed, watch, ref, Ref, ComputedRef } from 'vue'; import { useStore } from 'src/store'; import { container } from 'src/v2/common'; import { IInflationRepository, ISubscanRepository } from 'src/v2/repositories'; import { Symbols } from 'src/v2/symbols'; import { InflationConfiguration } from 'src/v2/models'; import { $api } from 'src/boot/api'; -import { useDappStaking } from 'src/staking-v3'; +import { InflationParam, useDappStaking } from 'src/staking-v3'; import { ethers } from 'ethers'; import { useNetworkInfo } from './useNetworkInfo'; -export function useInflation() { +type UseInflation = { + activeInflationConfiguration: ComputedRef; + estimatedInflation: Ref; + inflationParameters: Ref; + maximumInflationData: Ref<[number, number][]>; + realizedInflationData: Ref<[number, number][]>; + realizedAdjustableStakersPart: Ref; + fetchActiveConfigurationToStore: () => Promise; + fetchInflationParamsToStore: () => Promise; + getInflationParameters: () => Promise; +}; + +export function useInflation(): UseInflation { const store = useStore(); - const { eraLengths } = useDappStaking(); + const { eraLengths, currentEraInfo } = useDappStaking(); const { networkNameSubstrate } = useNetworkInfo(); const estimatedInflation = ref(undefined); + const maximumInflationData = ref<[number, number][]>([]); + const realizedInflationData = ref<[number, number][]>([]); + const realizedAdjustableStakersPart = ref(0); const activeInflationConfiguration = computed( () => store.getters['general/getActiveInflationConfiguration'] ); + const inflationParameters = computed( + () => store.getters['general/getInflationParameters'] + ); const currentBlock = computed(() => store.getters['general/getCurrentBlock']); - const fetchActiveConfigurationToStore = async () => { + const fetchActiveConfigurationToStore = async (): Promise => { const inflationRepository = container.get(Symbols.InflationRepository); const activeConfiguration = await inflationRepository.getInflationConfiguration(); 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); + }; + + const getInflationParameters = async (): Promise => { + const inflationRepository = container.get(Symbols.InflationRepository); + return await inflationRepository.getInflationParams(); + }; + /** * Estimates the realized inflation rate percentage based on the actual total issuance at the beginning * and estimated total issuance at the end of the current cycle. @@ -44,11 +73,9 @@ export function useInflation() { 'NewInflationConfiguration' ); // Latest item in array is for the current inflation cycle. - const latestInflationConfigBlock = response.events[response.events.length - 1].block; + const initialCycleBlock = response.events[response.events.length - 1].block; - const initialIssuanceBlockHash = await $api.rpc.chain.getBlockHash( - latestInflationConfigBlock - 1 - ); + const initialIssuanceBlockHash = await $api.rpc.chain.getBlockHash(initialCycleBlock - 1); const apiAt = await $api.at(initialIssuanceBlockHash); const initialTotalIssuance = await apiAt.query.balances.totalIssuance(); const realizedTotalIssuance = await $api.query.balances.totalIssuance(); @@ -62,16 +89,15 @@ export function useInflation() { standardEraLength * periodsPerCycle * (standardErasPerBuildAndEarnPeriod + standardErasPerVotingPeriod); - const blockDifference = BigInt(currentBlock.value - latestInflationConfigBlock); + const blockDifference = BigInt(currentBlock.value - initialCycleBlock); const slope = BigInt(realizedTotalIssuance.sub(initialTotalIssuance).toString()) / blockDifference; // Estimate total issuance at the end of the current cycle. - const endOfCycleBlock = latestInflationConfigBlock + cycleLengthInBlocks; + const endOfCycleBlock = initialCycleBlock + cycleLengthInBlocks; const endOfCycleTotalIssuance = Number( ethers.utils.formatEther( - slope * BigInt(endOfCycleBlock - latestInflationConfigBlock) + - initialTotalIssuance.toBigInt() + slope * BigInt(endOfCycleBlock - initialCycleBlock) + initialTotalIssuance.toBigInt() ) ); @@ -81,6 +107,31 @@ export function useInflation() { (endOfCycleTotalIssuance - Number(ethers.utils.formatEther(initialTotalIssuance.toString())))) / endOfCycleTotalIssuance; + + // Calculate maximum and realized inflation for each era in the cycle. + calculateMaximumInflationData( + initialCycleBlock, + endOfCycleBlock, + initialTotalIssuance.toBigInt(), + cycleLengthInBlocks, + inflationParameters.value.maxInflationRate, + eraLengths.value.standardEraLength + ); + + calculateRealizedInflationData( + initialCycleBlock, + currentBlock.value, + slope, + eraLengths.value.standardEraLength, + initialTotalIssuance.toBigInt() + ); + + calculateAdjustableStakerRewards( + realizedTotalIssuance.toBigInt(), + currentEraInfo.value?.currentStakeAmount.totalStake ?? BigInt(0), + inflationParameters.value.adjustableStakersPart, + inflationParameters.value.idealStakingRate + ); } catch (error) { console.error('Error calculating realized inflation', error); } @@ -89,10 +140,72 @@ export function useInflation() { return inflation; }; + const calculateMaximumInflationData = ( + firstBlock: number, + lastBlock: number, + firstBlockIssuance: bigint, + cycleLengthInBlocks: number, + maxInflation: number, + eraLength: number + ): void => { + const result: [number, number][] = []; + const inflation = BigInt(Math.floor(maxInflation * 100)) * BigInt('10000000000000000'); + const cycleProgression = (firstBlockIssuance * inflation) / BigInt('1000000000000000000'); + const cycleLength = BigInt(cycleLengthInBlocks); + + // One sample per era. + for (let i = firstBlock; i <= lastBlock; i += eraLength) { + const inflation = + (cycleProgression * BigInt(i - firstBlock)) / cycleLength + firstBlockIssuance; + + result.push([i, Number(ethers.utils.formatEther(inflation.toString()))]); + } + + // console.log((result[result.length - 1][1] - result[0][1]) / result[result.length - 1][1]); + maximumInflationData.value = result; + }; + + const calculateRealizedInflationData = ( + firstBlock: number, + lastBlock: number, + slope: bigint, + eraLength: number, + firstBlockIssuance: bigint + ): void => { + const result: [number, number][] = []; + + for (let i = firstBlock; i <= lastBlock; i += eraLength) { + const currentBlockIssuance = Number( + ethers.utils.formatEther(slope * BigInt(i - firstBlock) + firstBlockIssuance) + ); + + result.push([i, currentBlockIssuance]); + } + + realizedInflationData.value = result; + }; + + const calculateAdjustableStakerRewards = ( + totalIssuance: bigint, + totalStake: bigint, + adjustableStakerPart: number, + idealStakingRate: number + ): void => { + const stakeRate = + totalStake <= BigInt(0) + ? 0 + : Number(ethers.utils.formatEther(totalStake.toString())) / + Number(ethers.utils.formatEther(totalIssuance.toString())); + const result = adjustableStakerPart * Math.min(1, stakeRate / idealStakingRate); + realizedAdjustableStakersPart.value = Number(result.toFixed(3)); + }; + watch( - [$api], + [activeInflationConfiguration, inflationParameters], async () => { - estimatedInflation.value = await estimateRealizedInflation(); + if (activeInflationConfiguration.value && inflationParameters.value) { + estimatedInflation.value = await estimateRealizedInflation(); + } }, { immediate: true } ); @@ -100,6 +213,12 @@ export function useInflation() { return { activeInflationConfiguration, estimatedInflation, + inflationParameters, + maximumInflationData, + realizedInflationData, + realizedAdjustableStakersPart, fetchActiveConfigurationToStore, + fetchInflationParamsToStore, + getInflationParameters, }; } diff --git a/src/i18n/en-US/index.ts b/src/i18n/en-US/index.ts index bea2dfc18..80f92802e 100644 --- a/src/i18n/en-US/index.ts +++ b/src/i18n/en-US/index.ts @@ -1,3 +1,5 @@ +import { treasury } from '@polkadot/types/interfaces/definitions'; + export default { confirm: 'Confirm', cancel: 'Cancel', @@ -44,14 +46,6 @@ export default { help: 'Help', share: 'Share', multisig: 'Multisig', - modals: { - yokiOrigins: { - introducing: 'Introducing a new experience on zkEVM', - experienceNow: 'Experience now', - learnMore: 'Learn more', - keep: 'Keep me on the Portal', - }, - }, sort: { sortBy: 'Sort by', amountHightToLow: 'Amount: High to Low', @@ -84,8 +78,6 @@ export default { ledgerUsers: 'Ledger Users', ledgerUsersImportantInformation: 'Important information regarding the upcoming transition to dApp Staking V3. Check out the details', - yoki: 'Yoki Origins', - yokiSignUp: 'Yoki Origins is a user onboarding journey on Astar zkEVM. Experience now!', stakingNotSupportZkEvm: 'dApps Staking is not supported on {networkNotSupport}, please switch to {networkSupport} and start staking!', connectedInvalidNetwork: 'Please connect to the correct network in your wallet', @@ -690,6 +682,20 @@ export default { burn: { burn: 'Burn', }, + inflation: { + adjustableInflation: 'Adjustable inflation', + treasury: 'Treasury', + collators: 'Collators', + baseStakers: 'Base stakers', + bonus: 'Bonus', + dAppRewards: 'dApp rewards', + adjustableStakers: 'Adjustable stakers', + adjustableStakersShort: 'Adj. stakers', + activeAdjustable: '{percentage}% is active', + currentInflationRate: 'Current inflation rate', + maximumInflation: 'Maximum inflation ({rate}%)', + realizedInflation: 'Realized inflation', + }, }, chart: { tvl: { diff --git a/src/layouts/DashboardLayout.vue b/src/layouts/DashboardLayout.vue index d3fcddc04..02467311a 100644 --- a/src/layouts/DashboardLayout.vue +++ b/src/layouts/DashboardLayout.vue @@ -6,7 +6,6 @@
    -
    @@ -27,13 +26,11 @@ import { useQuasar } from 'quasar'; import { LOCAL_STORAGE } from 'src/config/localStorage'; import { useStore } from 'src/store'; import UnderMaintenanceBanner from 'src/components/header/UnderMaintenanceBanner.vue'; -import YokiBanner from 'src/components/header/YokiBanner.vue'; export default defineComponent({ components: { PortalHeader, SidebarDesktop, - YokiBanner, }, setup() { const store = useStore(); diff --git a/src/links/index.ts b/src/links/index.ts index 673d2be56..3eba10af4 100644 --- a/src/links/index.ts +++ b/src/links/index.ts @@ -55,13 +55,6 @@ export const polkadotJsUrl = { }, }; -export const modals = { - yokiOrigins: { - learnMore: 'https://astar.network/blog/84017', - experienceNow: 'https://yoki.astar.network/', - }, -}; - export const getSubscanExtrinsic = ({ subscanBase, hash, diff --git a/src/staking-v3/hooks/useAprV3.ts b/src/staking-v3/hooks/useAprV3.ts index 8eeaace44..b819dbd66 100644 --- a/src/staking-v3/hooks/useAprV3.ts +++ b/src/staking-v3/hooks/useAprV3.ts @@ -13,11 +13,6 @@ export const useAprV3 = ({ isWatch }: { isWatch: boolean }) => { const bonusApr = ref(0); const { eraLengths, isVotingPeriod, currentEraInfo, stakerInfo } = useDappStaking(); - const percentageToNumber = (percent: string): number => { - // e.g.: percent 1%: 10000000000000000 - return Number(percent) * 0.0000000000000001 * 0.01; - }; - const toAstr = (wei: bigint): number => { return Number(ethers.utils.formatEther(String(wei))); }; @@ -49,10 +44,10 @@ export const useAprV3 = ({ isWatch }: { isWatch: boolean }) => { eraLength: EraLengths; }): number => { const numTotalIssuance = Number(ethers.utils.formatEther(totalIssuance.toString())); - const yearlyInflation = percentageToNumber(inflationParams.maxInflationRate); - const baseStakersPart = percentageToNumber(inflationParams.baseStakersPart); - const adjustableStakersPart = percentageToNumber(inflationParams.adjustableStakersPart); - const idealStakingRate = percentageToNumber(inflationParams.idealStakingRate); + const yearlyInflation = inflationParams.maxInflationRate; + const baseStakersPart = inflationParams.baseStakersPart; + const adjustableStakersPart = inflationParams.adjustableStakersPart; + const idealStakingRate = inflationParams.idealStakingRate; const cyclesPerYear = getCyclePerYear(eraLength); const currentStakeAmount = isVotingPeriod.value diff --git a/src/staking-v3/logic/models/DappStaking.ts b/src/staking-v3/logic/models/DappStaking.ts index 2b540b9ef..1bae9aac2 100644 --- a/src/staking-v3/logic/models/DappStaking.ts +++ b/src/staking-v3/logic/models/DappStaking.ts @@ -181,10 +181,14 @@ interface TierThreshold { } export interface InflationParam { - readonly maxInflationRate: string; - readonly adjustableStakersPart: string; - readonly baseStakersPart: string; - readonly idealStakingRate: string; + readonly maxInflationRate: number; + readonly treasuryPart: number; + readonly collatorsPart: number; + readonly dappsPart: number; + readonly baseStakersPart: number; + readonly adjustableStakersPart: number; + readonly bonusPart: number; + readonly idealStakingRate: number; } export enum TvlAmountType { diff --git a/src/store/general/getters.ts b/src/store/general/getters.ts index c6ee77b97..93bb9114b 100644 --- a/src/store/general/getters.ts +++ b/src/store/general/getters.ts @@ -12,6 +12,7 @@ import { import type { ChainInfo } from 'src/hooks/useChainInfo'; import type { Extensions } from 'src/hooks/useMetaExtensions'; import { InflationConfiguration } from 'src/v2/models'; +import { InflationParam } from 'src/staking-v3'; export interface GeneralGetters { initialized(state: State): boolean; @@ -36,6 +37,7 @@ export interface GeneralGetters { getCurrentBlock(state: State): number; getUnifiedAccount(state: State): UnifiedAccount | undefined; getActiveInflationConfiguration(state: State): InflationConfiguration | undefined; + getInflationParameters(state: State): InflationParam | undefined; } const getters: GetterTree & GeneralGetters = { @@ -63,6 +65,7 @@ const getters: GetterTree & GeneralGetters = { getCurrentBlock: (state: State) => state.currentBlock, getUnifiedAccount: (state: State) => state.unifiedAccount, getActiveInflationConfiguration: (state: State) => state.activeInflationConfiguration, + getInflationParameters: (state: State) => state.inflationParameters, }; export default getters; diff --git a/src/store/general/mutations.ts b/src/store/general/mutations.ts index c8fbca699..7640e1891 100644 --- a/src/store/general/mutations.ts +++ b/src/store/general/mutations.ts @@ -12,6 +12,7 @@ import { UnifiedAccount, } from './state'; import { InflationConfiguration } from 'src/v2/models'; +import { InflationParam } from 'src/staking-v3'; export interface GeneralMutations { setInitialized(state: S): void; @@ -33,6 +34,7 @@ export interface GeneralMutations { setCurrentBlock(state: S, blockNumber: number): void; setUnifiedAccount(state: S, unifiedAccount: UnifiedAccount): void; setActiveInflationConfiguration(state: S, inflationConfiguration: InflationConfiguration): void; + setInflationParameters(state: S, inflationParams: InflationParam): void; } const mutation: MutationTree & GeneralMutations = { @@ -116,6 +118,9 @@ const mutation: MutationTree & GeneralMutations = { setActiveInflationConfiguration(state, inflationConfiguration) { state.activeInflationConfiguration = inflationConfiguration; }, + setInflationParameters(state, inflationParams) { + state.inflationParameters = inflationParams; + }, }; export default mutation; diff --git a/src/store/general/state.ts b/src/store/general/state.ts index 375281187..6c161700e 100644 --- a/src/store/general/state.ts +++ b/src/store/general/state.ts @@ -3,6 +3,7 @@ import type { Extensions } from 'src/hooks/useMetaExtensions'; import { endpointKey } from 'src/config/chainEndpoints'; import { LOCAL_STORAGE } from 'src/config/localStorage'; import { InflationConfiguration, NftMetadata } from 'src/v2/models'; +import { InflationParam } from 'src/staking-v3'; export type SubstrateAccount = { address: string; @@ -68,6 +69,7 @@ export interface GeneralStateInterface { currentBlock: number; unifiedAccount?: UnifiedAccount; activeInflationConfiguration: InflationConfiguration | undefined; + inflationParameters: InflationParam | undefined; } function state(): GeneralStateInterface { @@ -110,6 +112,7 @@ function state(): GeneralStateInterface { gas: undefined, currentBlock: 0, activeInflationConfiguration: undefined, + inflationParameters: undefined, }; } diff --git a/src/v2/models/Inflation.ts b/src/v2/models/Inflation.ts index e960fc7c4..42943d35f 100644 --- a/src/v2/models/Inflation.ts +++ b/src/v2/models/Inflation.ts @@ -12,11 +12,15 @@ export interface PalletInflationActiveInflationConfig extends Struct { readonly idealStakingRate: Perquintill; } -export interface PalletInflationInflationParams extends Struct { - readonly maxInflationRate: String; - readonly adjustableStakersPart: String; - readonly baseStakersPart: String; - readonly idealStakingRate: String; +export interface PalletInflationInflationParameters extends Struct { + readonly maxInflationRate: Compact; + readonly treasuryPart: Compact; + readonly collatorsPart: Compact; + readonly dappsPart: Compact; + readonly baseStakersPart: Compact; + readonly adjustableStakersPart: Compact; + readonly bonusPart: Compact; + readonly idealStakingRate: Compact; } export interface InflationConfiguration { diff --git a/src/v2/repositories/implementations/InflationRepository.ts b/src/v2/repositories/implementations/InflationRepository.ts index c84436716..485da49e0 100644 --- a/src/v2/repositories/implementations/InflationRepository.ts +++ b/src/v2/repositories/implementations/InflationRepository.ts @@ -1,14 +1,18 @@ import { InflationConfiguration, PalletInflationActiveInflationConfig, - PalletInflationInflationParams, + PalletInflationInflationParameters, } from 'src/v2/models'; import { IInflationRepository } from '../IInflationRepository'; import { inject, injectable } from 'inversify'; import { Symbols } from 'src/v2/symbols'; import { IApi } from 'src/v2/integration'; import { InflationParam } from 'src/staking-v3'; -import { BlockHash } from '@polkadot/types/interfaces'; +import { BlockHash, Perquintill } from '@polkadot/types/interfaces'; +import { Compact } from '@polkadot/types'; + +const quntilToNumber = (value: Compact): number => + Number(value.toHuman()?.toString().replace('%', '') ?? 0) / 100; @injectable() export class InflationRepository implements IInflationRepository { @@ -34,13 +38,17 @@ export class InflationRepository implements IInflationRepository { public async getInflationParams(): Promise { const api = await this.api.getApi(); - const data = await api.query.inflation.inflationParams(); + const data = await api.query.inflation.inflationParams(); return { - maxInflationRate: String(data.maxInflationRate), - adjustableStakersPart: String(data.adjustableStakersPart), - baseStakersPart: String(data.baseStakersPart), - idealStakingRate: String(data.idealStakingRate), + maxInflationRate: quntilToNumber(data.maxInflationRate), + adjustableStakersPart: quntilToNumber(data.adjustableStakersPart), + baseStakersPart: quntilToNumber(data.baseStakersPart), + idealStakingRate: quntilToNumber(data.idealStakingRate), + treasuryPart: quntilToNumber(data.treasuryPart), + collatorsPart: quntilToNumber(data.collatorsPart), + dappsPart: quntilToNumber(data.dappsPart), + bonusPart: quntilToNumber(data.bonusPart), }; }