From 150bab32f1f25f362723111cfd47b9b955c37600 Mon Sep 17 00:00:00 2001 From: David de Kloet Date: Thu, 18 Jul 2024 13:11:08 +0200 Subject: [PATCH] Add getters on SnsSummaryWrapper for fields from swap.params --- .../project-detail/ProjectCommitment.svelte | 14 ++++----- .../project-detail/ProjectSwapDetails.svelte | 24 +++++++-------- frontend/src/lib/services/neurons.services.ts | 1 + frontend/src/lib/types/sns-summary-wrapper.ts | 28 ++++++++++++++++++ frontend/src/lib/utils/projects.utils.ts | 29 ++++++++++--------- frontend/src/lib/utils/sns.utils.ts | 7 +++-- .../tests/lib/utils/projects.utils.spec.ts | 4 +-- 7 files changed, 67 insertions(+), 40 deletions(-) diff --git a/frontend/src/lib/components/project-detail/ProjectCommitment.svelte b/frontend/src/lib/components/project-detail/ProjectCommitment.svelte index 403b613e46c..b39333bc9d5 100644 --- a/frontend/src/lib/components/project-detail/ProjectCommitment.svelte +++ b/frontend/src/lib/components/project-detail/ProjectCommitment.svelte @@ -7,7 +7,7 @@ PROJECT_DETAIL_CONTEXT_KEY, type ProjectDetailContext, } from "$lib/types/project-detail.context"; - import type { SnsSummary } from "$lib/types/sns"; + import type { SnsSummaryWrapper } from "$lib/types/sns-summary-wrapper"; import { getProjectCommitmentSplit, isCommitmentSplitWithNeuronsFund, @@ -22,7 +22,6 @@ KeyValuePair, KeyValuePairInfo, } from "@dfinity/gix-components"; - import type { SnsParams } from "@dfinity/sns"; import { ICPToken, TokenAmountV2 } from "@dfinity/utils"; import { nonNullish } from "@dfinity/utils"; import { getContext } from "svelte"; @@ -31,17 +30,16 @@ PROJECT_DETAIL_CONTEXT_KEY ); - let summary: SnsSummary; + let summary: SnsSummaryWrapper; // type safety validation is done in ProjectStatusSection component - $: summary = $projectDetailStore.summary as SnsSummary; - - let params: SnsParams; - $: ({ params } = summary.swap); + $: summary = $projectDetailStore.summary as SnsSummaryWrapper; let min_icp_e8s: bigint; let max_icp_e8s: bigint; let min_participants: number; - $: ({ min_icp_e8s, max_icp_e8s, min_participants } = params); + $: min_icp_e8s = summary.getMinIcpE8s(); + $: max_icp_e8s = summary.getMaxIcpE8s(); + $: min_participants = summary.getMinParticipants(); let projectCommitments: ProjectCommitmentSplit; $: projectCommitments = getProjectCommitmentSplit(summary); diff --git a/frontend/src/lib/components/project-detail/ProjectSwapDetails.svelte b/frontend/src/lib/components/project-detail/ProjectSwapDetails.svelte index 4f00e42da49..61cce4ce282 100644 --- a/frontend/src/lib/components/project-detail/ProjectSwapDetails.svelte +++ b/frontend/src/lib/components/project-detail/ProjectSwapDetails.svelte @@ -11,12 +11,11 @@ PROJECT_DETAIL_CONTEXT_KEY, type ProjectDetailContext, } from "$lib/types/project-detail.context"; - import type { SnsSummary } from "$lib/types/sns"; + import type { SnsSummaryWrapper } from "$lib/types/sns-summary-wrapper"; import { formatNumber } from "$lib/utils/format.utils"; import TestIdWrapper from "../common/TestIdWrapper.svelte"; import AmountDisplay from "../ic/AmountDisplay.svelte"; import { KeyValuePair } from "@dfinity/gix-components"; - import type { SnsParams } from "@dfinity/sns"; import { ICPToken, TokenAmountV2 } from "@dfinity/utils"; import { nonNullish } from "@dfinity/utils"; import { getContext } from "svelte"; @@ -26,30 +25,27 @@ ); // type safety validation is done in ProjectDetail component - let summary: SnsSummary; - $: summary = $projectDetailStore.summary as SnsSummary; + let summary: SnsSummaryWrapper; + $: summary = $projectDetailStore.summary as SnsSummaryWrapper; - let params: SnsParams; let token: IcrcTokenMetadata; - $: ({ - swap: { params }, - token, - } = summary); + $: token = summary.token; let minCommitmentIcp: TokenAmountV2; $: minCommitmentIcp = TokenAmountV2.fromUlps({ - amount: params.min_participant_icp_e8s, + amount: summary.getMinParticipantIcpE8s(), token: ICPToken, }); + let maxCommitmentIcp: TokenAmountV2; $: maxCommitmentIcp = TokenAmountV2.fromUlps({ - amount: params.max_participant_icp_e8s, + amount: summary.getMaxParticipantIcpE8s(), token: ICPToken, }); let snsTokens: TokenAmountV2; $: snsTokens = TokenAmountV2.fromUlps({ - amount: params.sns_token_e8s, + amount: summary.getSnsTokenE8s(), token, }); @@ -83,7 +79,7 @@ {$i18n.sns_project_detail.min_participants} {formatNumber(params.min_participants, { + >{formatNumber(summary.getMinParticipants(), { minFraction: 0, maxFraction: 0, })}{$i18n.sns_project_detail.sale_end} diff --git a/frontend/src/lib/services/neurons.services.ts b/frontend/src/lib/services/neurons.services.ts index 22c6da844e4..2b122872893 100644 --- a/frontend/src/lib/services/neurons.services.ts +++ b/frontend/src/lib/services/neurons.services.ts @@ -987,6 +987,7 @@ export const makeDummyProposals = async (neuronId: NeuronId): Promise => { const { snsSummariesStore } = await import("../stores/sns.store"); const projects = get(snsSummariesStore); const pendingProject = projects.find( + // Use 1 instead of using enum to avoid importing sns-js (summary) => summary.getLifecycle() === 1 ); await makeDummyProposalsApi({ diff --git a/frontend/src/lib/types/sns-summary-wrapper.ts b/frontend/src/lib/types/sns-summary-wrapper.ts index df0c67be225..a3c0616899d 100644 --- a/frontend/src/lib/types/sns-summary-wrapper.ts +++ b/frontend/src/lib/types/sns-summary-wrapper.ts @@ -63,6 +63,34 @@ export class SnsSummaryWrapper implements SnsSummary { return fromDefinedNullable(this.lifecycle.lifecycle); } + getSwapDueTimestampSeconds(): bigint { + return this.swap.params.swap_due_timestamp_seconds; + } + + getMinIcpE8s(): bigint { + return this.swap.params.min_icp_e8s; + } + + getMaxIcpE8s(): bigint { + return this.swap.params.max_icp_e8s; + } + + getMinParticipants(): number { + return this.swap.params.min_participants; + } + + getMinParticipantIcpE8s(): bigint { + return this.swap.params.min_participant_icp_e8s; + } + + getMaxParticipantIcpE8s(): bigint { + return this.swap.params.max_participant_icp_e8s; + } + + getSnsTokenE8s(): bigint { + return this.swap.params.sns_token_e8s; + } + public overrideDerivedState( newDerivedState: SnsSwapDerivedState ): SnsSummaryWrapper { diff --git a/frontend/src/lib/utils/projects.utils.ts b/frontend/src/lib/utils/projects.utils.ts index ab4dcfdfb7c..a752a6fc511 100644 --- a/frontend/src/lib/utils/projects.utils.ts +++ b/frontend/src/lib/utils/projects.utils.ts @@ -89,27 +89,28 @@ export const durationTillSwapStart = ({ * - remaining commitment to reach project maximum */ export const currentUserMaxCommitment = ({ - summary: { swap, derived }, + summary, swapCommitment, }: { - summary: SnsSummary; + summary: SnsSummaryWrapper; swapCommitment: SnsSwapCommitment | undefined | null; }): bigint => { const remainingProjectCommitment = - swap.params.max_icp_e8s - derived.buyer_total_icp_e8s; + summary.getMaxIcpE8s() - summary.derived.buyer_total_icp_e8s; const remainingUserCommitment = - swap.params.max_participant_icp_e8s - + summary.getMaxParticipantIcpE8s() - (getCommitmentE8s(swapCommitment) ?? 0n); return remainingProjectCommitment < remainingUserCommitment ? remainingProjectCommitment : remainingUserCommitment; }; -export const projectRemainingAmount = ({ swap, derived }: SnsSummary): bigint => - swap.params.max_icp_e8s - derived.buyer_total_icp_e8s; +export const projectRemainingAmount = (summary: SnsSummaryWrapper): bigint => + summary.getMaxIcpE8s() - summary.derived.buyer_total_icp_e8s; const isProjectOpen = (summary: SnsSummaryWrapper): boolean => summary.getLifecycle() === SnsSwapLifecycle.Open; + // Checks whether the amount that the user wants to contribute is lower than the minimum for the project. // It takes into account the current commitment of the user. const commitmentTooSmall = ({ @@ -119,15 +120,17 @@ const commitmentTooSmall = ({ project: SnsFullProject; amount: TokenAmount; }): boolean => - summary.swap.params.min_participant_icp_e8s > + summary.getMinParticipantIcpE8s() > amount.toE8s() + (getCommitmentE8s(swapCommitment) ?? 0n); + const commitmentTooLarge = ({ summary, amountE8s, }: { - summary: SnsSummary; + summary: SnsSummaryWrapper; amountE8s: bigint; -}): boolean => summary.swap.params.max_participant_icp_e8s < amountE8s; +}): boolean => summary.getMaxParticipantIcpE8s() < amountE8s; + // Checks whether the amount that the user wants to contribute // plus the amount that all users have contributed so far // exceeds the maximum amount that the project can accept. @@ -135,7 +138,7 @@ export const commitmentExceedsAmountLeft = ({ summary, amountE8s, }: { - summary: SnsSummary; + summary: SnsSummaryWrapper; amountE8s: bigint; }): boolean => projectRemainingAmount(summary) < amountE8s; @@ -221,7 +224,7 @@ export const validParticipation = ({ labelKey: "error__sns.not_enough_amount", substitutions: { $amount: formatTokenE8s({ - value: project.summary.swap.params.min_participant_icp_e8s, + value: project.summary.getMinParticipantIcpE8s(), detailed: true, }), }, @@ -241,7 +244,7 @@ export const validParticipation = ({ value: getCommitmentE8s(project.swapCommitment) ?? 0n, }), $maxCommitment: formatTokenE8s({ - value: project.summary.swap.params.max_participant_icp_e8s, + value: project.summary.getMaxParticipantIcpE8s(), }), }, }; @@ -259,7 +262,7 @@ export const validParticipation = ({ $commitment: formatTokenE8s({ value: totalCommitment }), $remainingCommitment: formatTokenE8s({ value: - project.summary.swap.params.max_icp_e8s - + project.summary.getMaxIcpE8s() - project.summary.derived.buyer_total_icp_e8s, }), }, diff --git a/frontend/src/lib/utils/sns.utils.ts b/frontend/src/lib/utils/sns.utils.ts index 6ea724f3a72..3d4404f318c 100644 --- a/frontend/src/lib/utils/sns.utils.ts +++ b/frontend/src/lib/utils/sns.utils.ts @@ -2,7 +2,8 @@ import { SECONDS_IN_DAY } from "$lib/constants/constants"; import { MIN_VALID_SNS_GENERIC_NERVOUS_SYSTEM_FUNCTION_ID } from "$lib/constants/sns-proposals.constants"; import type { SnsTicketsStoreData } from "$lib/stores/sns-tickets.store"; import type { TicketStatus } from "$lib/types/sale"; -import type { SnsSummary, SnsSwapCommitment } from "$lib/types/sns"; +import type { SnsSwapCommitment } from "$lib/types/sns"; +import type { SnsSummaryWrapper } from "$lib/types/sns-summary-wrapper"; import { AccountIdentifier, SubAccount } from "@dfinity/ledger-icp"; import type { Principal } from "@dfinity/principal"; import type { @@ -167,11 +168,11 @@ export const swapEndedMoreThanOneWeekAgo = ({ summary, nowInSeconds, }: { - summary: SnsSummary; + summary: SnsSummaryWrapper; nowInSeconds: number; }) => { const oneWeekAgoInSeconds = BigInt(nowInSeconds - SECONDS_IN_DAY * 7); - return oneWeekAgoInSeconds > summary.swap.params.swap_due_timestamp_seconds; + return oneWeekAgoInSeconds > summary.getSwapDueTimestampSeconds(); }; /** diff --git a/frontend/src/tests/lib/utils/projects.utils.spec.ts b/frontend/src/tests/lib/utils/projects.utils.spec.ts index 9daf77850fe..a188d2b0886 100644 --- a/frontend/src/tests/lib/utils/projects.utils.spec.ts +++ b/frontend/src/tests/lib/utils/projects.utils.spec.ts @@ -1,6 +1,6 @@ import { NOT_LOADED } from "$lib/constants/stores.constants"; import type { SnsFullProject } from "$lib/derived/sns/sns-projects.derived"; -import type { SnsSummary, SnsSwapCommitment } from "$lib/types/sns"; +import type { SnsSwapCommitment } from "$lib/types/sns"; import type { SnsSummaryWrapper } from "$lib/types/sns-summary-wrapper"; import { nowInSeconds } from "$lib/utils/date.utils"; import { @@ -612,7 +612,7 @@ describe("project-utils", () => { it("returns remaining amount taking into account current commitment", () => { const projectMax = 10_000_000_000n; const projectCommitment = 9_200_000_000n; - const summary: SnsSummary = mockSnsFullProject.summary.override({ + const summary = mockSnsFullProject.summary.override({ derived: { buyer_total_icp_e8s: projectCommitment, sns_tokens_per_icp: 1,