diff --git a/frontend/src/lib/stores/sns-aggregator.store.ts b/frontend/src/lib/stores/sns-aggregator.store.ts index 209968d3ad6..869bbc9964f 100644 --- a/frontend/src/lib/stores/sns-aggregator.store.ts +++ b/frontend/src/lib/stores/sns-aggregator.store.ts @@ -35,6 +35,9 @@ const initSnsAggreagatorStore = export const snsAggregatorIncludingAbortedProjectsStore = initSnsAggreagatorStore(); +// This project has been abandoned https://dfinity.slack.com/archives/C039M7YS6F6/p1733302975333649 +const CYCLES_TRANSFER_STATION_ROOT_CANISTER_ID = "ibahq-taaaa-aaaaq-aadna-cai"; + export const snsAggregatorStore: SnsAggregatorStore = derived( snsAggregatorIncludingAbortedProjectsStore, (store) => { @@ -46,55 +49,52 @@ export const snsAggregatorStore: SnsAggregatorStore = derived( if (isNullish(data)) return { data: undefined }; - // TODO: Find a better way to fix broken SNS metadata. These transformations will be remove once we have a better solution. - const handledAbandonedSnsData = data?.map(fixBrokenSnsMetadataBasedOnId); - const sortedAbandonesSnsData = sortedListBasedOnAbandoned( - handledAbandonedSnsData + const cts = data.find( + (sns) => + sns.list_sns_canisters.root === CYCLES_TRANSFER_STATION_ROOT_CANISTER_ID ); - const cachedSnsData = sortedAbandonesSnsData.map( - ({ isAbandoned: _, ...sns }) => ({ ...sns }) + if (isNullish(cts)) return { data }; + const dataWithoutCts = data.filter( + (sns) => + sns.list_sns_canisters.root !== CYCLES_TRANSFER_STATION_ROOT_CANISTER_ID ); return { - data: cachedSnsData, + data: [...dataWithoutCts, overrideCyclesTransferStation(cts)], }; } ); -const brokenSnsOverrides: Record< - string, - { name: string; tokenSymbol: string } -> = { - // Overrided for CYCLES_TRANSFER_STATION as discussed in https://dfinity.slack.com/archives/C039M7YS6F6/p1733302975333649 - "ibahq-taaaa-aaaaq-aadna-cai": { - name: "CYCLES-TRANSFER-STATION", - tokenSymbol: "CTS", - }, -}; - -const fixBrokenSnsMetadataBasedOnId = ( +const overrideCyclesTransferStation = ( sns: CachedSnsDto ): CachedSnsDto & { isAbandoned?: boolean } => { - const override = brokenSnsOverrides[sns.list_sns_canisters.root]; - - // Required for the tokens and staking routes as they apply their own sort logic const hiddenCharacterToPushSnsToEndOfList = "\u200B"; - if (!nonNullish(override)) return sns; + const originalName = "CYCLES-TRANSFER-STATION"; + const originalSymbol = "CTS"; + let name = sns.meta.name; + + if (name !== originalName) { + name = `${hiddenCharacterToPushSnsToEndOfList}${name} (formerly ${originalName})`; + } + const newMeta = { ...sns.meta, - name: `${hiddenCharacterToPushSnsToEndOfList}${sns.meta.name} (formerly ${override.name})`, + name, }; const newIcrc1Metadata = sns.icrc1_metadata.map< [string, CachedSnsTokenMetadataDto[0][1]] >(([name, value]) => { if (name === "icrc1:symbol" && "Text" in value) { - return [ - name, - { - Text: `${value.Text} (${override.tokenSymbol})`, - }, - ]; + const symbol = value.Text; + if (symbol !== originalSymbol) { + return [ + name, + { + Text: `${symbol} (${originalSymbol})`, + }, + ]; + } } return [name, value]; }); @@ -106,15 +106,3 @@ const fixBrokenSnsMetadataBasedOnId = ( isAbandoned: true, }; }; - -// Required for the proposals route as it doesnt apply sort logic -const sortedListBasedOnAbandoned = ( - list: (CachedSnsDto & { isAbandoned?: boolean })[] -) => [ - ...list.sort((a, b) => { - if (a.isAbandoned && !b.isAbandoned) return 1; - if (!a.isAbandoned && b.isAbandoned) return -1; - - return 0; - }), -]; diff --git a/frontend/src/tests/lib/stores/sns-aggregator.store.spec.ts b/frontend/src/tests/lib/stores/sns-aggregator.store.spec.ts index 12586b5a1ab..8f74831c691 100644 --- a/frontend/src/tests/lib/stores/sns-aggregator.store.spec.ts +++ b/frontend/src/tests/lib/stores/sns-aggregator.store.spec.ts @@ -176,6 +176,28 @@ describe("sns-aggregator store", () => { rootCanisterId: "ibahq-taaaa-aaaaq-aadna-cai", }); + const fixedBrokenSns = withBrokenSns({ + sns: { + ...mockedSns, + meta: { + ...mockedSns.meta, + name: "CYCLES-TRANSFER-STATION", + }, + icrc1_metadata: [...mockedSns.icrc1_metadata].map(([name, value]) => { + if (name === "icrc1:symbol" && "Text" in value) { + return [ + name, + { + Text: "CTS", + }, + ]; + } + return [name, value]; + }), + }, + rootCanisterId: "ibahq-taaaa-aaaaq-aadna-cai", + }); + it("should override information for SNS with rootCanisterId ibahq-taaaa-aaaaq-aadna-cai", () => { const data = [brokenSns]; snsAggregatorIncludingAbortedProjectsStore.setData(data); @@ -194,7 +216,7 @@ describe("sns-aggregator store", () => { expect(result.icrc1_metadata[3][1]).toEqual({ Text: "--- (CTS)" }); }); - it("should sort sns by temporary isAbandoded property", () => { + it("should send the CTS SNS to the bottom of the store", () => { const data = [brokenSns, ...aggregatorMockSnsesDataDto]; snsAggregatorIncludingAbortedProjectsStore.setData(data); expect( @@ -212,5 +234,22 @@ describe("sns-aggregator store", () => { ); expect(result.icrc1_metadata[3][1]).toEqual({ Text: "--- (CTS)" }); }); + + it("should not override CTS SNS if the metadata returns to its original value", () => { + const data = [fixedBrokenSns, ...aggregatorMockSnsesDataDto]; + snsAggregatorIncludingAbortedProjectsStore.setData(data); + expect( + get(snsAggregatorIncludingAbortedProjectsStore).data[0].meta.name + ).toBe("CYCLES-TRANSFER-STATION"); + expect( + get(snsAggregatorIncludingAbortedProjectsStore).data[0] + .icrc1_metadata[3][1] + ).toEqual({ Text: "CTS" }); + + const result = + get(snsAggregatorStore).data[get(snsAggregatorStore).data.length - 1]; + expect(result.meta.name).toBe("CYCLES-TRANSFER-STATION"); + expect(result.icrc1_metadata[3][1]).toEqual({ Text: "CTS" }); + }); }); });