From 835bd85d8940496240f3a70de93c1292e3674974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Mon, 23 Dec 2024 14:49:43 +0100 Subject: [PATCH] fix(#2571): add support for searching by cip-129 identifiers --- CHANGELOG.md | 3 +- govtool/backend/sql/list-dreps.sql | 2 +- govtool/frontend/package-lock.json | 4 +- ...nceActionNewCommitteeDetailsTabContent.tsx | 4 +- .../src/components/organisms/DRepCard.tsx | 108 +++++++++++++----- .../components/organisms/DRepDetailsCard.tsx | 19 ++- govtool/frontend/src/i18n/locales/en.json | 1 + .../src/services/requests/getDRepList.ts | 22 +++- .../src/services/requests/getProposals.ts | 16 ++- govtool/metadata-validation/package-lock.json | 4 +- 10 files changed, 145 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e77f1fb49..11ff20c91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ changes. - -## [v2.0.2](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.2) 2024-12-20 +## [v2.0.2](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.2) 2024-12-23 ### Added @@ -37,6 +37,7 @@ changes. - Move matomo initalization out of the react code - Fix some non-ipfs related errors while fetching the DRep images [Issue 2546](https://github.com/IntersectMBO/govtool/issues/2546) - Remaining mobile responsiveness issue [Issue 2493](https://github.com/IntersectMBO/govtool/issues/2493) +- Fix searching by CIP-129 identifiers [Issue 2571](https://github.com/IntersectMBO/govtool/issues/2571) ### Changed diff --git a/govtool/backend/sql/list-dreps.sql b/govtool/backend/sql/list-dreps.sql index 043b316d2..e6518a7cb 100644 --- a/govtool/backend/sql/list-dreps.sql +++ b/govtool/backend/sql/list-dreps.sql @@ -26,7 +26,7 @@ SELECT encode(va.data_hash, 'hex'), dr_deposit.deposit, DRepDistr.amount, -(DRepActivity.epoch_no - Max(coalesce(block.epoch_no, block_first_register.epoch_no))) <= DRepActivity.drep_activity AS active, + (DRepActivity.epoch_no - Max(coalesce(block.epoch_no, block_first_register.epoch_no))) <= DRepActivity.drep_activity AS active, encode(dr_voting_anchor.tx_hash, 'hex') AS tx_hash, newestRegister.time AS last_register_time, COALESCE(latestDeposit.deposit, 0), diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 55b16c656..24d068e3d 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "@govtool/frontend", - "version": "2.0.1", + "version": "2.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govtool/frontend", - "version": "2.0.1", + "version": "2.0.2", "hasInstallScript": true, "dependencies": { "@emotion/react": "^11.11.1", diff --git a/govtool/frontend/src/components/molecules/GovernanceActionNewCommitteeDetailsTabContent.tsx b/govtool/frontend/src/components/molecules/GovernanceActionNewCommitteeDetailsTabContent.tsx index 920b72b08..fc244db2f 100644 --- a/govtool/frontend/src/components/molecules/GovernanceActionNewCommitteeDetailsTabContent.tsx +++ b/govtool/frontend/src/components/molecules/GovernanceActionNewCommitteeDetailsTabContent.tsx @@ -21,7 +21,7 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({ .filter((member) => member.newExpirationEpoch === undefined) .map((member) => ({ cip129Identifier: encodeCIP129Identifier({ - txID: member.hash, + txID: (member.hasScript ? "02" : "13") + member.hash, bech32Prefix: member.hasScript ? "cc_hot" : "cc_cold", }), expirationEpoch: member.expirationEpoch, @@ -31,7 +31,7 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({ .filter((member) => member.newExpirationEpoch !== undefined) .map((member) => ({ cip129Identifier: encodeCIP129Identifier({ - txID: member.hash, + txID: (member.hasScript ? "02" : "13") + member.hash, bech32Prefix: member.hasScript ? "cc_hot" : "cc_cold", }), expirationEpoch: member.expirationEpoch, diff --git a/govtool/frontend/src/components/organisms/DRepCard.tsx b/govtool/frontend/src/components/organisms/DRepCard.tsx index ed044d0ba..75f17b725 100644 --- a/govtool/frontend/src/components/organisms/DRepCard.tsx +++ b/govtool/frontend/src/components/organisms/DRepCard.tsx @@ -10,6 +10,7 @@ import { Card } from "@molecules"; import { correctDRepDirectoryFormat, ellipsizeText, + encodeCIP129Identifier, getMetadataDataMissingStatusTranslation, } from "@utils"; @@ -24,7 +25,16 @@ type DRepCardProps = { }; export const DRepCard = ({ - dRep: { status, type, view, votingPower, givenName, metadataStatus, image }, + dRep: { + status, + type, + view, + votingPower, + givenName, + metadataStatus, + image, + drepId, + }, isConnected, isDelegationLoading, isInProgress, @@ -48,6 +58,11 @@ export const DRepCard = ({ }, }); + const cip129Identifier = encodeCIP129Identifier({ + txID: `22${drepId}`, + bech32Prefix: "drep", + }); + return ( - { - navigator.clipboard.writeText(view); - addSuccessAlert(t("alerts.copiedToClipboard")); - e.stopPropagation(); - }} + - { + navigator.clipboard.writeText(view); + addSuccessAlert(t("alerts.copiedToClipboard")); + e.stopPropagation(); + }} + sx={{ + gap: 1, + width: "250px", + maxWidth: { + xxs: "200px", + xs: "100%", + }, + "&:hover": { + opacity: 0.6, + transition: "opacity 0.3s", + }, + }} > - {view} - - - + + {view} + + + + { + navigator.clipboard.writeText(cip129Identifier); + addSuccessAlert(t("alerts.copiedToClipboard")); + e.stopPropagation(); + }} + sx={{ + gap: 1, + width: "250px", + maxWidth: { + xxs: "200px", + xs: "100%", + }, + "&:hover": { + opacity: 0.6, + transition: "opacity 0.3s", + }, + display: "flex", + flexDirection: "row", + }} + > + + (CIP-129){" "} + + {cip129Identifier} + + + + + diff --git a/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx b/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx index 90518a64a..196802c30 100644 --- a/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx +++ b/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx @@ -6,7 +6,11 @@ import { ICONS, PATHS } from "@consts"; import { useCardano, useModal } from "@context"; import { useDelegateTodRep, useScreenDimension, useTranslation } from "@hooks"; import { Card, DataMissingInfoBox } from "@molecules"; -import { correctAdaFormat, testIdFromLabel } from "@utils"; +import { + correctAdaFormat, + encodeCIP129Identifier, + testIdFromLabel, +} from "@utils"; import { DRepData } from "@/models"; import { DRepDetailsCardHeader } from "./DRepDetailsCardHeader"; @@ -41,6 +45,7 @@ export const DRepDetailsCard = ({ status, url, view, + drepId, votingPower, } = dRepData; @@ -109,6 +114,18 @@ export const DRepDetailsCard = ({ + + + diff --git a/govtool/frontend/src/i18n/locales/en.json b/govtool/frontend/src/i18n/locales/en.json index f9faf8cbc..19bef3aeb 100644 --- a/govtool/frontend/src/i18n/locales/en.json +++ b/govtool/frontend/src/i18n/locales/en.json @@ -747,6 +747,7 @@ "copiedLink": "Copied link", "delegate": "Delegate", "drepId": "DRep ID", + "cip129DrepId": "(CIP-129) DRep ID", "email": "Email", "feedback": "Feedback", "filter": "Filter", diff --git a/govtool/frontend/src/services/requests/getDRepList.ts b/govtool/frontend/src/services/requests/getDRepList.ts index 532f7ee60..5005e1313 100644 --- a/govtool/frontend/src/services/requests/getDRepList.ts +++ b/govtool/frontend/src/services/requests/getDRepList.ts @@ -8,7 +8,11 @@ import { DrepDataDTO, } from "@models"; import { API } from "../API"; -import { mapDtoToDrep } from "@/utils"; +import { + decodeCIP129Identifier, + encodeCIP129Identifier, + mapDtoToDrep, +} from "@/utils"; export type GetDRepListArguments = { filters?: string[]; @@ -34,6 +38,22 @@ export const getDRepList = async ({ const { words } = bech32.decode(rawSearchPhrase); return bech32.encode("drep", words); } + if (rawSearchPhrase.startsWith("drep")) { + const decodedIdentifier = decodeCIP129Identifier(rawSearchPhrase); + if (decodedIdentifier) { + const isCIP129Identifier = decodedIdentifier.txID.startsWith("22"); + if (isCIP129Identifier) { + return encodeCIP129Identifier({ + txID: decodedIdentifier.txID.slice(2), + bech32Prefix: "drep", + }); + } + return encodeCIP129Identifier({ + txID: decodedIdentifier.txID, + bech32Prefix: "drep", + }); + } + } return rawSearchPhrase; })(); diff --git a/govtool/frontend/src/services/requests/getProposals.ts b/govtool/frontend/src/services/requests/getProposals.ts index 333cad371..9e9fef4d0 100644 --- a/govtool/frontend/src/services/requests/getProposals.ts +++ b/govtool/frontend/src/services/requests/getProposals.ts @@ -1,7 +1,11 @@ import { Infinite, ProposalData, ProposalDataDTO } from "@models"; import { API } from "../API"; -import { mapDtoToProposal } from "@/utils"; +import { + decodeCIP129Identifier, + getFullGovActionId, + mapDtoToProposal, +} from "@/utils"; export type GetProposalsArguments = { dRepID?: string; @@ -18,9 +22,17 @@ export const getProposals = async ({ page = 0, // It allows fetch proposals and if we have 7 items, display 6 cards and "view all" button pageSize = 7, - searchPhrase = "", + searchPhrase: rawSearchPhrase = "", sorting = "", }: GetProposalsArguments): Promise> => { + const searchPhrase = (() => { + if (rawSearchPhrase.startsWith("gov_action")) { + const { txID } = decodeCIP129Identifier(rawSearchPhrase); + return getFullGovActionId(txID, 0); + } + + return rawSearchPhrase; + })(); const response = await API.get>("/proposal/list", { params: { page, diff --git a/govtool/metadata-validation/package-lock.json b/govtool/metadata-validation/package-lock.json index 061b263db..e31f70cbf 100644 --- a/govtool/metadata-validation/package-lock.json +++ b/govtool/metadata-validation/package-lock.json @@ -1,12 +1,12 @@ { "name": "@govtool/metadata-validation", - "version": "2.0.0", + "version": "2.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govtool/metadata-validation", - "version": "2.0.0", + "version": "2.0.2", "license": "UNLICENSED", "dependencies": { "@nestjs/axios": "^3.0.2",