From 88407bf477dd7c703d894fef67c8ab637fcaf5d4 Mon Sep 17 00:00:00 2001 From: Max Strasinsky Date: Wed, 15 Jan 2025 14:54:32 +0100 Subject: [PATCH 01/15] Add getNetworkEconomicsParameters api --- .../api-services/governance.api-service.ts | 4 +++ frontend/src/lib/api/governance.api.ts | 21 +++++++++++ .../src/tests/lib/api/governance.api.spec.ts | 35 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/frontend/src/lib/api-services/governance.api-service.ts b/frontend/src/lib/api-services/governance.api-service.ts index 47b463282c5..4848104a444 100644 --- a/frontend/src/lib/api-services/governance.api-service.ts +++ b/frontend/src/lib/api-services/governance.api-service.ts @@ -5,6 +5,7 @@ import { claimOrRefreshNeuron, claimOrRefreshNeuronByMemo, disburse, + getNetworkEconomicsParameters, increaseDissolveDelay, joinCommunityFund, leaveCommunityFund, @@ -149,6 +150,9 @@ export const governanceApiService = { }; return neuronsCache.neurons; }, + getNetworkEconomicsParameters(params: ApiQueryParams) { + return getNetworkEconomicsParameters(params); + }, // Action calls async addHotkey(params: ApiManageHotkeyParams) { diff --git a/frontend/src/lib/api/governance.api.ts b/frontend/src/lib/api/governance.api.ts index bab89b62684..b03b3904a88 100644 --- a/frontend/src/lib/api/governance.api.ts +++ b/frontend/src/lib/api/governance.api.ts @@ -9,6 +9,7 @@ import type { Agent, Identity } from "@dfinity/agent"; import type { E8s, KnownNeuron, + NetworkEconomics, NeuronId, NeuronInfo, ProposalId, @@ -593,3 +594,23 @@ export const changeNeuronVisibility = async ({ `Visibility change complete for ${neuronIds.length} neurons. IDs: ${neuronIds.join(", ")}. New visibility: ${visibility}` ); }; + +export const getNetworkEconomicsParameters = async ({ + identity, + certified, +}: ApiQueryParams): Promise => { + logWithTimestamp( + `Getting network economics parameters call certified: ${certified}...` + ); + + const { canister: governance } = await governanceCanister({ identity }); + const response = await governance.getNetworkEconomicsParameters({ + certified, + }); + + logWithTimestamp( + `Getting network economics parameters call certified: ${certified} complete.` + ); + + return response; +}; diff --git a/frontend/src/tests/lib/api/governance.api.spec.ts b/frontend/src/tests/lib/api/governance.api.spec.ts index d86c9a2a7ad..7e66cabbb08 100644 --- a/frontend/src/tests/lib/api/governance.api.spec.ts +++ b/frontend/src/tests/lib/api/governance.api.spec.ts @@ -4,6 +4,7 @@ import { changeNeuronVisibility, claimOrRefreshNeuronByMemo, disburse, + getNetworkEconomicsParameters, increaseDissolveDelay, joinCommunityFund, leaveCommunityFund, @@ -840,4 +841,38 @@ describe("neurons-api", () => { }); }); }); + + describe("getNetworkEconomicsParameters", () => { + const identity = mockIdentity; + + it("should call the canister to get the network economics parameters", async () => { + const certified = true; + await getNetworkEconomicsParameters({ + certified, + identity, + }); + expect( + mockGovernanceCanister.getNetworkEconomicsParameters + ).toHaveBeenCalledTimes(1); + expect( + mockGovernanceCanister.getNetworkEconomicsParameters + ).toHaveBeenCalledWith({ certified }); + }); + + it("throws error when call fails", async () => { + const error = new Error(); + mockGovernanceCanister.getNetworkEconomicsParameters.mockImplementation( + vi.fn(() => { + throw error; + }) + ); + + const call = () => + getNetworkEconomicsParameters({ + identity: mockIdentity, + certified: true, + }); + await expect(call).rejects.toThrow(error); + }); + }); }); From e93002e5dc3108372b4dae790b2ea7fd189a8373 Mon Sep 17 00:00:00 2001 From: Max Strasinsky Date: Wed, 15 Jan 2025 15:44:30 +0100 Subject: [PATCH 02/15] New networkEconomicsParametersStore --- frontend/src/lib/derived/debug.derived.ts | 4 ++ .../src/lib/stores/network-economics.store.ts | 32 ++++++++++++++ .../stores/network-economics.store.spec.ts | 22 ++++++++++ .../src/tests/mocks/network-economics.mock.ts | 42 +++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 frontend/src/lib/stores/network-economics.store.ts create mode 100644 frontend/src/tests/lib/stores/network-economics.store.spec.ts create mode 100644 frontend/src/tests/mocks/network-economics.mock.ts diff --git a/frontend/src/lib/derived/debug.derived.ts b/frontend/src/lib/derived/debug.derived.ts index e7669e90536..6c82399b924 100644 --- a/frontend/src/lib/derived/debug.derived.ts +++ b/frontend/src/lib/derived/debug.derived.ts @@ -10,6 +10,7 @@ import { importedTokensStore, } from "$lib/stores/imported-tokens.store"; import { knownNeuronsStore } from "$lib/stores/known-neurons.store"; +import { networkEconomicsParametersStore } from "$lib/stores/network-economics.store"; import { neuronsStore } from "$lib/stores/neurons.store"; import { proposalPayloadsStore, @@ -123,6 +124,7 @@ export const initDebugStore = () => defaultIcrcCanistersStore, importedTokensStore, failedImportedTokenLedgerIdsStore, + networkEconomicsParametersStore, ], ([ $busyStore, @@ -153,6 +155,7 @@ export const initDebugStore = () => $defaultIcrcCanistersStore, $importedTokensStore, $failedImportedTokenLedgerIdsStore, + $networkEconomicsParametersStore, ]) => ({ busy: $busyStore, accounts: $accountsStore, @@ -182,5 +185,6 @@ export const initDebugStore = () => defaultIcrcCanistersStore: $defaultIcrcCanistersStore, importedTokensStore: $importedTokensStore, failedImportedTokenLedgerIdsStore: $failedImportedTokenLedgerIdsStore, + networkEconomicsParametersStore: $networkEconomicsParametersStore, }) ); diff --git a/frontend/src/lib/stores/network-economics.store.ts b/frontend/src/lib/stores/network-economics.store.ts new file mode 100644 index 00000000000..71b47b452bb --- /dev/null +++ b/frontend/src/lib/stores/network-economics.store.ts @@ -0,0 +1,32 @@ +import type { NetworkEconomics } from "@dfinity/nns"; +import { writable, type Readable } from "svelte/store"; + +export interface NetworkEconomicsStoreData { + parameters: NetworkEconomics | undefined; + certified: boolean | undefined; +} + +export interface NetworkEconomicsStore + extends Readable { + setParameters: (data: NetworkEconomicsStoreData) => void; +} + +/** + * A store that contains the [network economics parameters](https://github.com/dfinity/ic/blob/d90e934eb440c730d44d9d9b1ece2cc3f9505d05/rs/nns/governance/proto/ic_nns_governance/pb/v1/governance.proto#L1847). + */ +const initNetworkEconomicsParametersStore = () => { + const { subscribe, set } = writable({ + parameters: undefined, + certified: undefined, + }); + + return { + subscribe, + + setParameters(parameters: NetworkEconomicsStoreData) { + set(parameters); + }, + }; +}; + +export const networkEconomicsStore = initNetworkEconomicsParametersStore(); diff --git a/frontend/src/tests/lib/stores/network-economics.store.spec.ts b/frontend/src/tests/lib/stores/network-economics.store.spec.ts new file mode 100644 index 00000000000..2699f24f886 --- /dev/null +++ b/frontend/src/tests/lib/stores/network-economics.store.spec.ts @@ -0,0 +1,22 @@ +import { get } from "svelte/store"; +import { networkEconomicsStore } from "../../../lib/stores/network-economics.store"; +import { mockNetworkEconomics } from "../../mocks/network-economics.mock"; + +describe("network-economics-store", () => { + it("should set parameters", () => { + expect(get(networkEconomicsStore)).toEqual({ + parameters: undefined, + certified: undefined, + }); + + networkEconomicsStore.setParameters({ + parameters: mockNetworkEconomics, + certified: true, + }); + + expect(get(networkEconomicsStore)).toEqual({ + parameters: mockNetworkEconomics, + certified: true, + }); + }); +}); diff --git a/frontend/src/tests/mocks/network-economics.mock.ts b/frontend/src/tests/mocks/network-economics.mock.ts new file mode 100644 index 00000000000..eb9956e7c53 --- /dev/null +++ b/frontend/src/tests/mocks/network-economics.mock.ts @@ -0,0 +1,42 @@ +import { + SECONDS_IN_HALF_YEAR, + SECONDS_IN_MONTH, +} from "$lib/constants/constants"; +import type { NetworkEconomics } from "@dfinity/nns"; + +export const mockNetworkEconomics: NetworkEconomics = { + neuronMinimumStake: 100_000_000n, + maxProposalsToKeepPerTopic: 1_000, + neuronManagementFeePerProposal: 10_000n, + rejectCost: 10_000_000n, + transactionFee: 1_000n, + neuronSpawnDissolveDelaySeconds: 3600n * 24n * 7n, + minimumIcpXdrRate: 1n, + maximumNodeProviderRewards: 10_000_000_000n, + neuronsFundEconomics: { + minimumIcpXdrRate: { + basisPoints: 123n, + }, + maxTheoreticalNeuronsFundParticipationAmountXdr: { + humanReadable: "456", + }, + neuronsFundMatchedFundingCurveCoefficients: { + contributionThresholdXdr: { + humanReadable: "789", + }, + oneThirdParticipationMilestoneXdr: { + humanReadable: "123", + }, + fullParticipationMilestoneXdr: { + humanReadable: "456", + }, + }, + maximumIcpXdrRate: { + basisPoints: 456n, + }, + }, + votingPowerEconomics: { + startReducingVotingPowerAfterSeconds: BigInt(SECONDS_IN_HALF_YEAR), + clearFollowingAfterSeconds: BigInt(SECONDS_IN_MONTH), + }, +}; From b89fc2154e2658a555ead79a0ba83f292be20006 Mon Sep 17 00:00:00 2001 From: Max Strasinsky Date: Wed, 15 Jan 2025 15:45:55 +0100 Subject: [PATCH 03/15] Add networkEconomicsStore to debug store --- frontend/src/lib/derived/debug.derived.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/lib/derived/debug.derived.ts b/frontend/src/lib/derived/debug.derived.ts index 6c82399b924..c2089f76c44 100644 --- a/frontend/src/lib/derived/debug.derived.ts +++ b/frontend/src/lib/derived/debug.derived.ts @@ -10,7 +10,7 @@ import { importedTokensStore, } from "$lib/stores/imported-tokens.store"; import { knownNeuronsStore } from "$lib/stores/known-neurons.store"; -import { networkEconomicsParametersStore } from "$lib/stores/network-economics.store"; +import { networkEconomicsStore } from "$lib/stores/network-economics.store"; import { neuronsStore } from "$lib/stores/neurons.store"; import { proposalPayloadsStore, @@ -124,7 +124,7 @@ export const initDebugStore = () => defaultIcrcCanistersStore, importedTokensStore, failedImportedTokenLedgerIdsStore, - networkEconomicsParametersStore, + networkEconomicsStore, ], ([ $busyStore, From 118f24dc7ee3a47712fdd55863a50bb0af95b52d Mon Sep 17 00:00:00 2001 From: Max Strasinsky Date: Wed, 15 Jan 2025 15:46:44 +0100 Subject: [PATCH 04/15] Load network economics on app load --- frontend/src/lib/services/app.services.ts | 5 +++++ .../services/network-economics.services.ts | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 frontend/src/lib/services/network-economics.services.ts diff --git a/frontend/src/lib/services/app.services.ts b/frontend/src/lib/services/app.services.ts index bb1e5d54e55..34b7d1605b2 100644 --- a/frontend/src/lib/services/app.services.ts +++ b/frontend/src/lib/services/app.services.ts @@ -3,8 +3,12 @@ import { loadActionableSnsProposals } from "$lib/services/actionable-sns-proposa import { initAccounts } from "$lib/services/icp-accounts.services"; import { loadImportedTokens } from "$lib/services/imported-tokens.services"; import { loadSnsProjects } from "$lib/services/public/sns.services"; +import { loadNetworkEconomicsParameters } from "./network-economics.services"; export const initAppPrivateData = async (): Promise => { + const initNetworkEconomicsParameters: Promise[] = [ + loadNetworkEconomicsParameters(), + ]; const initNns: Promise[] = [initAccounts()]; // Reload the SNS projects even if they were loaded. // Get latest data and create wrapper caches for the logged in identity. @@ -17,6 +21,7 @@ export const initAppPrivateData = async (): Promise => { * If Nns load but Sns load fails it is "fine" to go on because Nns are core features. */ await Promise.allSettled([ + Promise.all(initNetworkEconomicsParameters), Promise.all(initNns), Promise.all(initImportedTokens), Promise.all(initSns), diff --git a/frontend/src/lib/services/network-economics.services.ts b/frontend/src/lib/services/network-economics.services.ts new file mode 100644 index 00000000000..a48c13a481e --- /dev/null +++ b/frontend/src/lib/services/network-economics.services.ts @@ -0,0 +1,22 @@ +import { governanceApiService } from "../api-services/governance.api-service"; +import { networkEconomicsStore } from "../stores/network-economics.store"; +import { getAuthenticatedIdentity } from "./auth.services"; + +export const loadNetworkEconomicsParameters = async (): Promise => { + try { + const identity = await getAuthenticatedIdentity(); + const parameters = await governanceApiService.getNetworkEconomicsParameters( + { + identity, + certified: true, + } + ); + + networkEconomicsStore.setParameters({ + parameters, + certified: true, + }); + } catch (error) { + console.error(error); + } +}; From ffc28297584c43fcde6b5159079674c2bce6abed Mon Sep 17 00:00:00 2001 From: Max Strasinsky Date: Wed, 15 Jan 2025 17:53:02 +0100 Subject: [PATCH 05/15] Add voting power economics derived stores --- .../lib/derived/network-economics.derived.ts | 19 ++++++++++++ .../derived/network-economics.derived.spec.ts | 31 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 frontend/src/lib/derived/network-economics.derived.ts create mode 100644 frontend/src/tests/lib/derived/network-economics.derived.spec.ts diff --git a/frontend/src/lib/derived/network-economics.derived.ts b/frontend/src/lib/derived/network-economics.derived.ts new file mode 100644 index 00000000000..0a07c414002 --- /dev/null +++ b/frontend/src/lib/derived/network-economics.derived.ts @@ -0,0 +1,19 @@ +import { networkEconomicsStore } from "$lib/stores/network-economics.store"; +import { derived, type Readable } from "svelte/store"; + +export const startReducingVotingPowerAfterSecondsStore: Readable< + bigint | undefined +> = derived( + networkEconomicsStore, + ($networkEconomicsStore) => + $networkEconomicsStore.parameters?.votingPowerEconomics + ?.startReducingVotingPowerAfterSeconds +); + +export const clearFollowingAfterSecondsStore: Readable = + derived( + networkEconomicsStore, + ($networkEconomicsStore) => + $networkEconomicsStore.parameters?.votingPowerEconomics + ?.clearFollowingAfterSeconds + ); diff --git a/frontend/src/tests/lib/derived/network-economics.derived.spec.ts b/frontend/src/tests/lib/derived/network-economics.derived.spec.ts new file mode 100644 index 00000000000..29e06d1c0d1 --- /dev/null +++ b/frontend/src/tests/lib/derived/network-economics.derived.spec.ts @@ -0,0 +1,31 @@ +import { + clearFollowingAfterSecondsStore, + startReducingVotingPowerAfterSecondsStore, +} from "$lib/derived/network-economics.derived"; +import { networkEconomicsStore } from "$lib/stores/network-economics.store"; +import { mockNetworkEconomics } from "$tests/mocks/network-economics.mock"; +import { get } from "svelte/store"; + +describe("network-economics-derived", () => { + it("should return start reducing voting power", () => { + expect(get(startReducingVotingPowerAfterSecondsStore)).toEqual(undefined); + + networkEconomicsStore.setParameters({ + parameters: mockNetworkEconomics, + certified: true, + }); + + expect(get(startReducingVotingPowerAfterSecondsStore)).toEqual(15778800n); + }); + + it("should return start reducing voting power", () => { + expect(get(clearFollowingAfterSecondsStore)).toEqual(undefined); + + networkEconomicsStore.setParameters({ + parameters: mockNetworkEconomics, + certified: true, + }); + + expect(get(clearFollowingAfterSecondsStore)).toEqual(2629800n); + }); +}); From 41ea85453cbb70c756f666d6504d9f1a2bdafa0b Mon Sep 17 00:00:00 2001 From: Max Strasinsky Date: Wed, 15 Jan 2025 17:54:43 +0100 Subject: [PATCH 06/15] Switch to economics in ConfirmFollowingBanner --- .../ConfirmFollowingBanner.svelte | 28 ++++++++++------- .../ConfirmFollowingBanner.spec.ts | 31 +++++++++++++++++++ 2 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 frontend/src/tests/lib/components/neuron-detail/ConfirmFollowingBanner.spec.ts diff --git a/frontend/src/lib/components/neuron-detail/ConfirmFollowingBanner.svelte b/frontend/src/lib/components/neuron-detail/ConfirmFollowingBanner.svelte index 31f11996ebd..e57447bd47b 100644 --- a/frontend/src/lib/components/neuron-detail/ConfirmFollowingBanner.svelte +++ b/frontend/src/lib/components/neuron-detail/ConfirmFollowingBanner.svelte @@ -4,21 +4,25 @@ import Banner from "$lib/components/ui/Banner.svelte"; import BannerIcon from "$lib/components/ui/BannerIcon.svelte"; import { replacePlaceholders } from "$lib/utils/i18n.utils"; - import { START_REDUCING_VOTING_POWER_AFTER_SECONDS } from "$lib/constants/neurons.constants"; import { secondsToDissolveDelayDuration } from "$lib/utils/date.utils"; + import { startReducingVotingPowerAfterSecondsStore } from "$lib/derived/network-economics.derived"; let title: string; $: title = $i18n.losing_rewards_banner.confirm_title; - - const text = replacePlaceholders($i18n.losing_rewards.description, { - $period: secondsToDissolveDelayDuration( - BigInt(START_REDUCING_VOTING_POWER_AFTER_SECONDS) - ), - }); - - - - - +{#if $startReducingVotingPowerAfterSecondsStore} + + + + + +{/if} diff --git a/frontend/src/tests/lib/components/neuron-detail/ConfirmFollowingBanner.spec.ts b/frontend/src/tests/lib/components/neuron-detail/ConfirmFollowingBanner.spec.ts new file mode 100644 index 00000000000..eda4b2634f0 --- /dev/null +++ b/frontend/src/tests/lib/components/neuron-detail/ConfirmFollowingBanner.spec.ts @@ -0,0 +1,31 @@ +import ConfirmFollowingBanner from "$lib/components/neuron-detail/ConfirmFollowingBanner.svelte"; +import { networkEconomicsStore } from "$lib/stores/network-economics.store"; +import { mockNetworkEconomics } from "$tests/mocks/network-economics.mock"; +import { ConfirmFollowingBannerPo } from "$tests/page-objects/ConfirmFollowingBanner.page-object"; +import { JestPageObjectElement } from "$tests/page-objects/jest.page-object"; +import { render } from "@testing-library/svelte"; + +describe("ConfirmFollowingBanner", () => { + const renderComponent = () => { + const { container } = render(ConfirmFollowingBanner, {}); + + return ConfirmFollowingBannerPo.under(new JestPageObjectElement(container)); + }; + + it("should be hidden w/o voting economics", async () => { + const po = renderComponent(); + + expect(await po.isPresent()).toBe(false); + }); + + it("should be rendered with voting economics available", async () => { + networkEconomicsStore.setParameters({ + parameters: mockNetworkEconomics, + certified: true, + }); + + const po = renderComponent(); + + expect(await po.isPresent()).toBe(true); + }); +}); From c7e984d8cda0f4d82fd5d4526ba07b256d6c0737 Mon Sep 17 00:00:00 2001 From: Max Strasinsky Date: Wed, 15 Jan 2025 18:08:53 +0100 Subject: [PATCH 07/15] Switch to economics in ConfirmFollowingBanner --- .../lib/components/neuron-detail/ConfirmFollowingBanner.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/lib/components/neuron-detail/ConfirmFollowingBanner.svelte b/frontend/src/lib/components/neuron-detail/ConfirmFollowingBanner.svelte index e57447bd47b..04d561713f6 100644 --- a/frontend/src/lib/components/neuron-detail/ConfirmFollowingBanner.svelte +++ b/frontend/src/lib/components/neuron-detail/ConfirmFollowingBanner.svelte @@ -6,12 +6,13 @@ import { replacePlaceholders } from "$lib/utils/i18n.utils"; import { secondsToDissolveDelayDuration } from "$lib/utils/date.utils"; import { startReducingVotingPowerAfterSecondsStore } from "$lib/derived/network-economics.derived"; + import { nonNullish } from "@dfinity/utils"; let title: string; $: title = $i18n.losing_rewards_banner.confirm_title; -{#if $startReducingVotingPowerAfterSecondsStore} +{#if nonNullish($startReducingVotingPowerAfterSecondsStore)} Date: Wed, 15 Jan 2025 18:09:17 +0100 Subject: [PATCH 08/15] reset network economics store --- frontend/src/lib/stores/network-economics.store.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/src/lib/stores/network-economics.store.ts b/frontend/src/lib/stores/network-economics.store.ts index 71b47b452bb..80ac2c38fe9 100644 --- a/frontend/src/lib/stores/network-economics.store.ts +++ b/frontend/src/lib/stores/network-economics.store.ts @@ -15,10 +15,12 @@ export interface NetworkEconomicsStore * A store that contains the [network economics parameters](https://github.com/dfinity/ic/blob/d90e934eb440c730d44d9d9b1ece2cc3f9505d05/rs/nns/governance/proto/ic_nns_governance/pb/v1/governance.proto#L1847). */ const initNetworkEconomicsParametersStore = () => { - const { subscribe, set } = writable({ + const initialStoreData: NetworkEconomicsStoreData = { parameters: undefined, certified: undefined, - }); + }; + const { subscribe, set } = + writable(initialStoreData); return { subscribe, @@ -26,6 +28,10 @@ const initNetworkEconomicsParametersStore = () => { setParameters(parameters: NetworkEconomicsStoreData) { set(parameters); }, + + reset() { + set(initialStoreData); + }, }; }; From dea54fbb568dad44b68e56c4ca54e850890e25d9 Mon Sep 17 00:00:00 2001 From: Max Strasinsky Date: Wed, 15 Jan 2025 18:09:52 +0100 Subject: [PATCH 09/15] Switch to economics in NnsNeuronRewardStatusAction --- .../NnsNeuronRewardStatusAction.svelte | 78 +++++++++---------- .../NnsNeuronRewardStatusAction.spec.ts | 21 +++++ 2 files changed, 60 insertions(+), 39 deletions(-) diff --git a/frontend/src/lib/components/neuron-detail/NnsNeuronRewardStatusAction.svelte b/frontend/src/lib/components/neuron-detail/NnsNeuronRewardStatusAction.svelte index 733f5645deb..b1a09290375 100644 --- a/frontend/src/lib/components/neuron-detail/NnsNeuronRewardStatusAction.svelte +++ b/frontend/src/lib/components/neuron-detail/NnsNeuronRewardStatusAction.svelte @@ -2,7 +2,6 @@ import ConfirmFollowingActionButton from "$lib/components/neuron-detail/actions/ConfirmFollowingActionButton.svelte"; import FollowNeuronsButton from "$lib/components/neuron-detail/actions/FollowNeuronsButton.svelte"; import CommonItemAction from "$lib/components/ui/CommonItemAction.svelte"; - import { START_REDUCING_VOTING_POWER_AFTER_SECONDS } from "$lib/constants/neurons.constants"; import { i18n } from "$lib/stores/i18n"; import { secondsToDissolveDelayDuration } from "$lib/utils/date.utils"; import { replacePlaceholders } from "$lib/utils/i18n.utils"; @@ -18,7 +17,8 @@ IconWarning, } from "@dfinity/gix-components"; import { type NeuronInfo } from "@dfinity/nns"; - import { secondsToDuration } from "@dfinity/utils"; + import { nonNullish, secondsToDuration } from "@dfinity/utils"; + import { startReducingVotingPowerAfterSecondsStore } from "$lib/derived/network-economics.derived"; export let neuron: NeuronInfo; @@ -66,46 +66,46 @@ } ); }; - - const tooltipText = replacePlaceholders($i18n.losing_rewards.description, { - $period: secondsToDissolveDelayDuration( - BigInt(START_REDUCING_VOTING_POWER_AFTER_SECONDS) - ), - }); - - - - - - {title} - - - - {getDescription(neuron)} - - - {#if isFollowingReset} - - {:else} - - {/if} - + + + + + {title} + + + + {getDescription(neuron)} + + + {#if isFollowingReset} + + {:else} + + {/if} + +{/if}