diff --git a/CHANGELOG.md b/CHANGELOG.md index 1accf1918..9a1ff8810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,29 @@ changes. - +## [v2.0.8](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.8) 2025-01-23 + +### Added + +- Add share DRep button to every DRep instead of only our own [Issue 2686](https://github.com/IntersectMBO/govtool/issues/2686) +- Show metadata anchor in Governance Action Details [Issue 2178](https://github.com/IntersectMBO/govtool/issues/2178) +- Handle unexpected drep info query result [Issue 2676](https://github.com/IntersectMBO/govtool/issues/2676) + +### Fixed + +- Fix usage of trim on missing label +- Fix blank screen when registering as a DRep [Issue 2408](https://github.com/IntersectMBO/govtool/issues/2408) + +### Changed + +- Bump cardano-node to 10.1.4 +- Make CIP-129 governance identifiers the default ones + +### Removed + +- Remove logging to sentry for DRep registration transaction [Issue 2681](https://github.com/IntersectMBO/govtool/issues/2681) +- Remove logging to sentry when delegation transaction fails [Issue 2682](https://github.com/IntersectMBO/govtool/issues/2682) + ## [v2.0.7](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.7) 2025-01-20 ### Added diff --git a/govtool/backend/Dockerfile b/govtool/backend/Dockerfile index ea0c3d15d..0ce34a2a9 100644 --- a/govtool/backend/Dockerfile +++ b/govtool/backend/Dockerfile @@ -4,4 +4,4 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG WORKDIR /src COPY . . RUN cabal build -RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.7/x/vva-be/build/vva-be/vva-be /usr/local/bin +RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.8/x/vva-be/build/vva-be/vva-be /usr/local/bin diff --git a/govtool/backend/Dockerfile.qovery b/govtool/backend/Dockerfile.qovery index 6b5b38703..9d5f95226 100644 --- a/govtool/backend/Dockerfile.qovery +++ b/govtool/backend/Dockerfile.qovery @@ -4,7 +4,7 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG WORKDIR /src COPY . . RUN cabal build -RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.7/x/vva-be/build/vva-be/vva-be /usr/local/bin +RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.8/x/vva-be/build/vva-be/vva-be /usr/local/bin # Expose the necessary port EXPOSE 9876 diff --git a/govtool/backend/sql/get-drep-info.sql b/govtool/backend/sql/get-drep-info.sql index a6f1b76d4..b9d93a6bc 100644 --- a/govtool/backend/sql/get-drep-info.sql +++ b/govtool/backend/sql/get-drep-info.sql @@ -215,3 +215,4 @@ FROM CROSS JOIN IsScriptHash LEFT JOIN off_chain_vote_data ON off_chain_vote_data.voting_anchor_id = LatestRegistrationEntry.voting_anchor_id LEFT JOIN off_chain_vote_drep_data ON off_chain_vote_drep_data.off_chain_vote_data_id = off_chain_vote_data.id +LIMIT 1 \ No newline at end of file diff --git a/govtool/backend/sql/get-stake-key-voting-power.sql b/govtool/backend/sql/get-stake-key-voting-power.sql index a6cdbfe43..5e178b245 100644 --- a/govtool/backend/sql/get-stake-key-voting-power.sql +++ b/govtool/backend/sql/get-stake-key-voting-power.sql @@ -1,46 +1,13 @@ -WITH RewardRest AS ( - SELECT - SUM(amount) AS amount, - addr_id - FROM - reward_rest - GROUP BY - addr_id -), -Reward AS ( - SELECT - SUM(amount) AS amount, - addr_id - FROM - reward - GROUP BY - addr_id -), -Balance AS ( - SELECT - COALESCE(SUM(uv.value), 0) AS amount, - sa.id AS addr_id, - encode(sa.hash_raw, 'hex') AS addr_raw - FROM - stake_address sa - JOIN utxo_view uv ON uv.stake_address_id = sa.id - GROUP BY - addr_id, - addr_raw -) SELECT - (COALESCE(rr.amount, 0) + COALESCE(r.amount, 0) + COALESCE(b.amount, 0)) AS total_balance, - b.addr_raw + COALESCE(SUM(tx_out.value), 0) AS voting_power, + stake_address.id as addr_id FROM - Balance b + stake_address +JOIN + tx_out on tx_out.stake_address_id = stake_address.id LEFT JOIN - RewardRest rr ON rr.addr_id = b.addr_id -LEFT JOIN - Reward r ON r.addr_id = rr.addr_id + tx_in ON tx_in.tx_out_id = tx_out.id AND tx_in.tx_out_index = tx_out.index WHERE - b.addr_id = (SELECT id FROM stake_address WHERE hash_raw = decode(?, 'hex')) + stake_address.hash_raw = decode(?, 'hex') AND tx_in.id IS NULL GROUP BY - b.addr_raw, - rr.amount, - r.amount, - b.amount \ No newline at end of file + stake_address.id; \ No newline at end of file diff --git a/govtool/backend/sql/list-dreps.sql b/govtool/backend/sql/list-dreps.sql index 5ccbfb1a7..b33a46cfc 100644 --- a/govtool/backend/sql/list-dreps.sql +++ b/govtool/backend/sql/list-dreps.sql @@ -35,168 +35,182 @@ LatestVoteEpoch AS ( JOIN block ON block.id = tx.block_id WHERE lvp.rn = 1 -) -SELECT DISTINCT ON (dh.raw) - encode(dh.raw, 'hex'), - dh.view, - dh.has_script, - va.url, - encode(va.data_hash, 'hex'), - dr_deposit.deposit, - DRepDistr.amount, - (DRepActivity.epoch_no - GREATEST(COALESCE(block.epoch_no, block_first_register.epoch_no), lve.epoch_no, newestRegister.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), - non_deregister_voting_anchor.url IS NOT NULL AS has_non_deregister_voting_anchor, - fetch_error.message, - off_chain_vote_drep_data.payment_address, - off_chain_vote_drep_data.given_name, - off_chain_vote_drep_data.objectives, - off_chain_vote_drep_data.motivations, - off_chain_vote_drep_data.qualifications, - off_chain_vote_drep_data.image_url, - off_chain_vote_drep_data.image_hash -FROM - drep_hash dh - JOIN ( - SELECT - dr.id, - dr.drep_hash_id, - dr.deposit, - ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn - FROM - drep_registration dr - WHERE - dr.deposit IS NOT NULL - ) AS dr_deposit ON dr_deposit.drep_hash_id = dh.id AND dr_deposit.rn = 1 - JOIN ( - SELECT +), +RankedDRepRegistration AS ( + SELECT dr.id, dr.drep_hash_id, dr.deposit, - ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn - FROM - drep_registration dr - ) AS latestDeposit ON latestDeposit.drep_hash_id = dh.id AND latestDeposit.rn = 1 - LEFT JOIN ( - SELECT - dr.id, - dr.drep_hash_id, dr.voting_anchor_id, ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn, - tx.hash AS tx_hash + encode(tx.hash, 'hex') AS tx_hash FROM drep_registration dr - JOIN tx ON tx.id = dr.tx_id - WHERE - COALESCE(dr.deposit, 0) >= 0 - ) AS dr_voting_anchor ON dr_voting_anchor.drep_hash_id = dh.id AND dr_voting_anchor.rn = 1 - LEFT JOIN ( - SELECT - dr.id, - dr.drep_hash_id, - dr.voting_anchor_id, - ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn, - tx.hash AS tx_hash - FROM - drep_registration dr - JOIN tx ON tx.id = dr.tx_id - ) AS dr_non_deregister_voting_anchor ON dr_non_deregister_voting_anchor.drep_hash_id = dh.id AND dr_non_deregister_voting_anchor.rn = 1 - LEFT JOIN ( - SELECT - dr.id, - dr.drep_hash_id, - dr.voting_anchor_id, - ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn - FROM - drep_registration dr - ) AS second_to_newest_drep_registration ON second_to_newest_drep_registration.drep_hash_id = dh.id AND second_to_newest_drep_registration.rn = 2 - LEFT JOIN DRepDistr ON DRepDistr.hash_id = dh.id AND DRepDistr.rn = 1 - LEFT JOIN voting_anchor va ON va.id = dr_voting_anchor.voting_anchor_id - LEFT JOIN voting_anchor non_deregister_voting_anchor ON non_deregister_voting_anchor.id = dr_non_deregister_voting_anchor.voting_anchor_id - LEFT JOIN ( - SELECT - fetch_error as message, - voting_anchor_id - FROM + JOIN tx ON tx.id = dr.tx_id +), +FetchError AS ( + SELECT + fetch_error as message, + voting_anchor_id + FROM + off_chain_vote_fetch_error + WHERE + fetch_time = ( + SELECT + max(fetch_time) + FROM off_chain_vote_fetch_error - WHERE - fetch_time = ( - SELECT - max(fetch_time) - FROM - off_chain_vote_fetch_error - ) - GROUP BY - fetch_error, - voting_anchor_id - ) AS fetch_error ON fetch_error.voting_anchor_id = va.id - LEFT JOIN off_chain_vote_data ON off_chain_vote_data.voting_anchor_id = va.id - LEFT JOIN off_chain_vote_drep_data ON off_chain_vote_drep_data.off_chain_vote_data_id = off_chain_vote_data.id - CROSS JOIN DRepActivity - LEFT JOIN voting_procedure ON voting_procedure.drep_voter = dh.id - LEFT JOIN tx ON tx.id = voting_procedure.tx_id - LEFT JOIN block ON block.id = tx.block_id - LEFT JOIN ( - SELECT - block.epoch_no, - block.time, - dr.drep_hash_id, - ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn - FROM + ) + GROUP BY + fetch_error, + voting_anchor_id +), +LatestExistingVotingAnchor AS ( + SELECT + dr.id AS drep_registration_id, + dr.drep_hash_id, + va.id AS voting_anchor_id, + va.url, + encode(va.data_hash, 'hex') AS metadata_hash + FROM + drep_registration dr + JOIN voting_anchor va ON dr.voting_anchor_id = va.id + JOIN off_chain_vote_data ocvd ON va.id = ocvd.voting_anchor_id + WHERE + ocvd.voting_anchor_id IS NOT NULL + ORDER BY + dr.tx_id DESC +), +HasNonDeregisterVotingAnchor AS ( + SELECT + dr.drep_hash_id, + EXISTS ( + SELECT 1 + FROM drep_registration dr_sub + WHERE + dr_sub.drep_hash_id = dr.drep_hash_id + AND dr_sub.voting_anchor_id IS NULL + AND COALESCE(dr_sub.deposit, 0) >= 0 + ) AS value + FROM + drep_registration dr + GROUP BY + dr.drep_hash_id +), +DRepData AS ( + SELECT DISTINCT ON (dh.raw) + encode(dh.raw, 'hex') drep_hash, + dh.view, + dh.has_script, + leva.url, + leva.metadata_hash, + COALESCE(dr_deposit.deposit, 0) as deposit, + DRepDistr.amount, + (DRepActivity.epoch_no - GREATEST(COALESCE(voting_procedure_block.epoch_no, block_first_register.epoch_no), lve.epoch_no, newestRegister.epoch_no)) <= DRepActivity.drep_activity AS active, + RankedDRepRegistration.tx_hash, + newestRegister.time AS last_register_time, + COALESCE(RankedDRepRegistration.deposit, 0) as latest_deposit, + hndva.value AS has_non_deregister_voting_anchor, + fetch_error.message AS fetch_error, + off_chain_vote_drep_data.payment_address, + off_chain_vote_drep_data.given_name, + off_chain_vote_drep_data.objectives, + off_chain_vote_drep_data.motivations, + off_chain_vote_drep_data.qualifications, + off_chain_vote_drep_data.image_url, + off_chain_vote_drep_data.image_hash + FROM + drep_hash dh + JOIN RankedDRepRegistration ON RankedDRepRegistration.drep_hash_id = dh.id AND RankedDRepRegistration.rn = 1 + JOIN ( + SELECT + dr.id, + dr.drep_hash_id, + dr.deposit, + ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn + FROM + drep_registration dr + WHERE + dr.deposit IS NOT NULL + ) AS dr_deposit ON dr_deposit.drep_hash_id = dh.id AND dr_deposit.rn = 1 + LEFT JOIN ( + SELECT + dr.id, + dr.drep_hash_id, + dr.deposit, + ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn + FROM + drep_registration dr + ) AS latestDeposit ON latestDeposit.drep_hash_id = dh.id AND latestDeposit.rn = 1 + LEFT JOIN LatestExistingVotingAnchor leva ON leva.drep_hash_id = dh.id + LEFT JOIN DRepDistr ON DRepDistr.hash_id = dh.id AND DRepDistr.rn = 1 + LEFT JOIN FetchError fetch_error ON fetch_error.voting_anchor_id = leva.voting_anchor_id + LEFT JOIN HasNonDeregisterVotingAnchor hndva ON hndva.drep_hash_id = dh.id + LEFT JOIN off_chain_vote_data ocvd ON ocvd.voting_anchor_id = leva.voting_anchor_id + LEFT JOIN off_chain_vote_drep_data ON off_chain_vote_drep_data.off_chain_vote_data_id = ocvd.id + LEFT JOIN voting_procedure ON voting_procedure.drep_voter = dh.id + LEFT JOIN tx voting_procedure_transaction ON voting_procedure_transaction.id = voting_procedure.tx_id + LEFT JOIN block voting_procedure_block ON voting_procedure_block.id = voting_procedure_transaction.block_id + LEFT JOIN ( + SELECT + block.epoch_no, + block.time, + dr.drep_hash_id, + ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn + FROM drep_registration dr JOIN tx ON tx.id = dr.tx_id JOIN block ON block.id = tx.block_id - WHERE - COALESCE(dr.deposit, 0) >= 0 - ) AS newestRegister ON newestRegister.drep_hash_id = dh.id AND newestRegister.rn = 1 - LEFT JOIN ( - SELECT - dr.tx_id, - dr.drep_hash_id, - ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id ASC) AS rn - FROM - drep_registration dr - ) AS dr_first_register ON dr_first_register.drep_hash_id = dh.id AND dr_first_register.rn = 1 - LEFT JOIN tx AS tx_first_register ON tx_first_register.id = dr_first_register.tx_id - LEFT JOIN block AS block_first_register ON block_first_register.id = tx_first_register.block_id - LEFT JOIN LatestVoteEpoch lve ON lve.drep_id = dh.id + WHERE + COALESCE(dr.deposit, 0) >= 0 + ) AS newestRegister ON newestRegister.drep_hash_id = dh.id AND newestRegister.rn = 1 + LEFT JOIN ( + SELECT + dr.tx_id, + dr.drep_hash_id, + ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id ASC) AS rn + FROM + drep_registration dr + ) AS dr_first_register ON dr_first_register.drep_hash_id = dh.id AND dr_first_register.rn = 1 + LEFT JOIN tx AS tx_first_register ON tx_first_register.id = dr_first_register.tx_id + LEFT JOIN block AS block_first_register ON block_first_register.id = tx_first_register.block_id + LEFT JOIN LatestVoteEpoch lve ON lve.drep_id = dh.id + CROSS JOIN DRepActivity + GROUP BY + dh.raw, + dh.view, + dh.has_script, + leva.url, + leva.metadata_hash, + dr_deposit.deposit, + DRepDistr.amount, + DRepActivity.epoch_no, + voting_procedure_block.epoch_no, + block_first_register.epoch_no, + lve.epoch_no, newestRegister.epoch_no, + DRepActivity.drep_activity, + RankedDRepRegistration.tx_hash, + newestRegister.time, + RankedDRepRegistration.deposit, + hndva.value, + fetch_error.message, + off_chain_vote_drep_data.payment_address, + off_chain_vote_drep_data.given_name, + off_chain_vote_drep_data.objectives, + off_chain_vote_drep_data.motivations, + off_chain_vote_drep_data.qualifications, + off_chain_vote_drep_data.image_url, + off_chain_vote_drep_data.image_hash +) +SELECT * FROM DRepData WHERE ( COALESCE(?, '') = '' OR - (CASE WHEN LENGTH(?) % 2 = 0 AND ? ~ '^[0-9a-fA-F]+$' THEN dh.raw = decode(?, 'hex') ELSE false END) OR - dh.view ILIKE ? OR - off_chain_vote_drep_data.given_name ILIKE ? OR - off_chain_vote_drep_data.payment_address ILIKE ? OR - off_chain_vote_drep_data.objectives ILIKE ? OR - off_chain_vote_drep_data.motivations ILIKE ? OR - off_chain_vote_drep_data.qualifications ILIKE ? - ) -GROUP BY - block_first_register.epoch_no, - block.epoch_no, - dh.raw, - second_to_newest_drep_registration.voting_anchor_id, - dh.view, - dh.has_script, - va.url, - va.data_hash, - dr_deposit.deposit, - DRepDistr.amount, - DRepActivity.epoch_no, - DRepActivity.drep_activity, - lve.epoch_no, - dr_voting_anchor.tx_hash, - newestRegister.time, - newestRegister.epoch_no, - latestDeposit.deposit, - non_deregister_voting_anchor.url, - fetch_error.message, - off_chain_vote_drep_data.payment_address, - off_chain_vote_drep_data.given_name, - off_chain_vote_drep_data.objectives, - off_chain_vote_drep_data.motivations, - off_chain_vote_drep_data.qualifications, - off_chain_vote_drep_data.image_url, - off_chain_vote_drep_data.image_hash; + (CASE WHEN LENGTH(?) % 2 = 0 AND ? ~ '^[0-9a-fA-F]+$' THEN drep_hash = ? ELSE false END) OR + view ILIKE ? OR + given_name ILIKE ? OR + payment_address ILIKE ? OR + objectives ILIKE ? OR + motivations ILIKE ? OR + qualifications ILIKE ? + ) \ No newline at end of file diff --git a/govtool/backend/src/VVA/API/Types.hs b/govtool/backend/src/VVA/API/Types.hs index 9cbf41690..3341f4860 100644 --- a/govtool/backend/src/VVA/API/Types.hs +++ b/govtool/backend/src/VVA/API/Types.hs @@ -585,8 +585,9 @@ deriveJSON (jsonOptions "dRepInfoResponse") ''DRepInfoResponse exampleDRepInfoResponse :: Text exampleDRepInfoResponse = - "{\"isRegisteredAsDRep\": false," - <> "\"wasRegisteredAsDRep\": true," + "{\"isScriptBased\": false," + <> "\"isRegisteredAsDRep\": true," + <> "\"wasRegisteredAsDRep\": false," <> "\"isRegisteredAsSoleVoter\": true," <> "\"wasRegisteredAsSoleVoter\": true," <> "\"deposit\": 2000000," diff --git a/govtool/backend/src/VVA/DRep.hs b/govtool/backend/src/VVA/DRep.hs index 1d0c7a1a8..187cdc73d 100644 --- a/govtool/backend/src/VVA/DRep.hs +++ b/govtool/backend/src/VVA/DRep.hs @@ -199,3 +199,4 @@ getDRepInfo drepId = withPool $ \conn -> do , dRepInfoImageHash = imageHash } [] -> return $ DRepInfo False False False False False Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing + _ -> error "Unexpected result from database query in getDRepInfo" diff --git a/govtool/backend/vva-be.cabal b/govtool/backend/vva-be.cabal index 7ae32cc47..a8b5cc157 100644 --- a/govtool/backend/vva-be.cabal +++ b/govtool/backend/vva-be.cabal @@ -1,6 +1,6 @@ cabal-version: 3.6 name: vva-be -version: 2.0.7 +version: 2.0.8 -- A short (one-line) description of the package. -- synopsis: diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 3479de187..77f8eafac 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "@govtool/frontend", - "version": "2.0.7", + "version": "2.0.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govtool/frontend", - "version": "2.0.7", + "version": "2.0.8", "hasInstallScript": true, "dependencies": { "@emotion/react": "^11.11.1", diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index 24f695d4c..4b259ad40 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -1,7 +1,7 @@ { "name": "@govtool/frontend", "private": true, - "version": "2.0.7", + "version": "2.0.8", "type": "module", "scripts": { "build": "vite build", diff --git a/govtool/frontend/src/components/molecules/DataMissingHeader.tsx b/govtool/frontend/src/components/molecules/DataMissingHeader.tsx index a1eae8bd8..6689de9e5 100644 --- a/govtool/frontend/src/components/molecules/DataMissingHeader.tsx +++ b/govtool/frontend/src/components/molecules/DataMissingHeader.tsx @@ -7,6 +7,8 @@ import { getMetadataDataMissingStatusTranslation, } from "@/utils"; import { ICONS } from "@/consts"; +import { Share } from "./Share"; +import { useScreenDimension } from "@/hooks"; type DataMissingHeaderProps = { isDataMissing: MetadataValidationStatus | null; @@ -24,6 +26,7 @@ export const DataMissingHeader = ({ image, }: DataMissingHeaderProps) => { const base64Image = getBase64ImageDetails(image ?? ""); + const { screenWidth } = useScreenDimension(); return ( + {screenWidth >= 1020 && } ); }; diff --git a/govtool/frontend/src/components/molecules/GovernanceActionCard.tsx b/govtool/frontend/src/components/molecules/GovernanceActionCard.tsx index 51ae0fdf9..68d880aed 100644 --- a/govtool/frontend/src/components/molecules/GovernanceActionCard.tsx +++ b/govtool/frontend/src/components/molecules/GovernanceActionCard.tsx @@ -118,18 +118,19 @@ export const GovernanceActionCard: FC = ({ ...props }) => { isSliderCard /> ; marginBottom?: number; + isSemiTransparent?: boolean; }; type PillVariantProps = BaseProps & { textVariant: "pill"; isCopyButton?: false; + isLinkButton?: false; }; type OtherVariantsProps = BaseProps & { textVariant?: "oneLine" | "twoLines" | "longText"; isCopyButton?: boolean; + isLinkButton?: boolean; }; type GovernanceActionCardElementProps = ( @@ -36,10 +41,14 @@ export const GovernanceActionCardElement = ({ isSliderCard, textVariant = "oneLine", isCopyButton, + isLinkButton, tooltipProps, marginBottom, isMarkdown = false, + isSemiTransparent = false, }: GovernanceActionCardElementProps) => { + const { openModal } = useModal(); + if (!text) { return null; } @@ -158,9 +167,12 @@ export const GovernanceActionCardElement = ({ WebkitLineClamp: 2, whiteSpace: "normal", }), - ...(isCopyButton && { + ...((isCopyButton || isLinkButton) && { color: "primaryBlue", }), + ...(isSemiTransparent && { + opacity: 0.75, + }), }} > {isMarkdown ? removeMarkdown(text) : text} @@ -171,6 +183,24 @@ export const GovernanceActionCardElement = ({ )} + {isLinkButton && ( + + link { + openModal({ + type: "externalLink", + state: { + externalLink: text.toString(), + }, + }); + }} + /> + + )} )} diff --git a/govtool/frontend/src/components/molecules/GovernanceVotedOnCard.tsx b/govtool/frontend/src/components/molecules/GovernanceVotedOnCard.tsx index b8ceb9cd6..6a25e7cb6 100644 --- a/govtool/frontend/src/components/molecules/GovernanceVotedOnCard.tsx +++ b/govtool/frontend/src/components/molecules/GovernanceVotedOnCard.tsx @@ -108,18 +108,19 @@ export const GovernanceVotedOnCard = ({ votedProposal, inProgress }: Props) => { isSliderCard /> {vote && ( { - navigator.clipboard.writeText(view); + navigator.clipboard.writeText(cip129Identifier); addSuccessAlert(t("alerts.copiedToClipboard")); e.stopPropagation(); }} @@ -169,6 +169,8 @@ export const DRepCard = ({ opacity: 0.6, transition: "opacity 0.3s", }, + display: "flex", + flexDirection: "row", }} > - {view} + {cip129Identifier} { - navigator.clipboard.writeText(cip129Identifier); + navigator.clipboard.writeText(view); addSuccessAlert(t("alerts.copiedToClipboard")); e.stopPropagation(); }} @@ -198,18 +200,16 @@ export const DRepCard = ({ opacity: 0.6, transition: "opacity 0.3s", }, - display: "flex", - flexDirection: "row", }} > - (CIP-129){" "} + (CIP-105){" "} - {cip129Identifier} + {view} diff --git a/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx b/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx index 77c7ac3af..ac4c5b2fe 100644 --- a/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx +++ b/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx @@ -112,13 +112,7 @@ export const DRepDetailsCard = ({ /> )} {/* ERROR MESSAGES END */} - - - - + + + + + + @@ -296,9 +302,14 @@ const DRepDetailsInfoItem = ({ type CopyableTextProps = { value: string; dataTestId: string; + isSemiTransparent?: boolean; }; -const CopyableText = ({ value, dataTestId }: CopyableTextProps) => ( +const CopyableText = ({ + value, + dataTestId, + isSemiTransparent, +}: CopyableTextProps) => ( { navigator.clipboard.writeText(value.toString()); @@ -314,7 +325,11 @@ const CopyableText = ({ value, dataTestId }: CopyableTextProps) => ( }, }} > - + {value} diff --git a/govtool/frontend/src/components/organisms/DRepDetailsCardHeader.tsx b/govtool/frontend/src/components/organisms/DRepDetailsCardHeader.tsx index ecbb61eba..6578d5d7c 100644 --- a/govtool/frontend/src/components/organisms/DRepDetailsCardHeader.tsx +++ b/govtool/frontend/src/components/organisms/DRepDetailsCardHeader.tsx @@ -10,7 +10,7 @@ import { useScreenDimension, useTranslation, } from "@hooks"; -import { DataMissingHeader, Share } from "@molecules"; +import { DataMissingHeader } from "@molecules"; import { correctDRepDirectoryFormat } from "@utils"; import { DRepData } from "@/models"; @@ -115,7 +115,6 @@ export const DRepDetailsCardHeader = ({ style={{ marginLeft: "4px" }} /> - {screenWidth >= 1020 && } )} diff --git a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx index 149eebeb3..8e89d0e1d 100644 --- a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx +++ b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx @@ -88,6 +88,7 @@ export const GovernanceActionDetailsCardData = ({ url, type, protocolParams, + metadataHash, }, }: GovernanceActionDetailsCardDataProps) => { const { epochParams } = useAppContext(); @@ -256,18 +257,19 @@ export const GovernanceActionDetailsCardData = ({ /> )} 1600 ? "longText" : "oneLine"} /> 1600 ? "longText" : "oneLine"} + isSemiTransparent /> {tabs?.length === 1 ? ( @@ -317,6 +319,21 @@ export const GovernanceActionDetailsCardData = ({ amount={withdrawal.amount} /> ))} + + + ); diff --git a/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/WhatRetirementMeans.tsx b/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/WhatRetirementMeans.tsx index 48f8a7db5..2f3421839 100644 --- a/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/WhatRetirementMeans.tsx +++ b/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/WhatRetirementMeans.tsx @@ -72,7 +72,7 @@ export const WhatRetirementMeans = ({ } catch (error: any) { Sentry.captureException(error); openWalletErrorModal({ - error, + error: error?.message ? error.message : JSON.stringify(error), onSumbit: onClickCancel, buttonText: t("modals.common.goToDashboard"), dataTestId: "retirement-transaction-error-modal", diff --git a/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts b/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts index 3d52255bf..dd92d59f7 100644 --- a/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts +++ b/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts @@ -176,7 +176,7 @@ export const useEditDRepInfoForm = ( Sentry.captureException(error); openWalletErrorModal({ - error, + error: error?.message ? error.message : JSON.stringify(error), onSumbit: () => backToDashboard(), dataTestId: "edit-drep-transaction-error-modal", }); diff --git a/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx b/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx index e2de25f10..61d017a12 100644 --- a/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx +++ b/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx @@ -3,7 +3,6 @@ import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; import { useFormContext } from "react-hook-form"; import { blake2bHex } from "blakejs"; -import * as Sentry from "@sentry/react"; import { NodeObject } from "jsonld"; import { CertificatesBuilder } from "@emurgo/cardano-serialization-lib-asmjs"; @@ -127,29 +126,23 @@ export const useRegisterAsdRepForm = ( async (data: DRepDataFormValues) => { if (!hash) return; const uri = data.storingURL; - try { - const certBuilder = CertificatesBuilder.new(); + const certBuilder = CertificatesBuilder.new(); - const registerCert = voter?.isRegisteredAsSoleVoter - ? await buildDRepUpdateCert(uri, hash) - : await buildDRepRegCert(uri, hash); + const registerCert = voter?.isRegisteredAsSoleVoter + ? await buildDRepUpdateCert(uri, hash) + : await buildDRepRegCert(uri, hash); - certBuilder.add(registerCert); + certBuilder.add(registerCert); - if (!registeredStakeKeysListState.length) { - const stakeKeyRegCert = await buildStakeKeyRegCert(); - certBuilder.add(stakeKeyRegCert); - } + if (!registeredStakeKeysListState.length) { + const stakeKeyRegCert = await buildStakeKeyRegCert(); + certBuilder.add(stakeKeyRegCert); + } - const voteDelegationCert = await buildVoteDelegationCert(dRepID); - certBuilder.add(voteDelegationCert); + const voteDelegationCert = await buildVoteDelegationCert(dRepID); + certBuilder.add(voteDelegationCert); - return certBuilder; - } catch (error) { - Sentry.setTag("hook", "useRegisterAsdRepForm"); - Sentry.captureException(error); - throw error; - } + return certBuilder; }, [ buildDRepRegCert, @@ -222,11 +215,8 @@ export const useRegisterAsdRepForm = ( }, }); } else { - Sentry.setTag("hook", "useRegisterAsdRepForm"); - Sentry.captureException(error); - openWalletErrorModal({ - error, + error: error?.message ? error.message : JSON.stringify(error), onSumbit: () => backToDashboard(), dataTestId: "registration-transaction-error-modal", }); diff --git a/govtool/frontend/src/hooks/forms/useVoteActionForm.tsx b/govtool/frontend/src/hooks/forms/useVoteActionForm.tsx index 4f215199a..d3a35ca06 100644 --- a/govtool/frontend/src/hooks/forms/useVoteActionForm.tsx +++ b/govtool/frontend/src/hooks/forms/useVoteActionForm.tsx @@ -3,7 +3,6 @@ import { useForm, useWatch } from "react-hook-form"; import * as Yup from "yup"; import { yupResolver } from "@hookform/resolvers/yup"; import { useLocation, useNavigate, useParams } from "react-router-dom"; -import * as Sentry from "@sentry/react"; import { PATHS } from "@consts"; import { useCardano, useSnackbar } from "@context"; @@ -106,8 +105,6 @@ export const useVoteActionForm = ({ }); } } catch (error) { - Sentry.setTag("hook", "useVoteActionForm"); - Sentry.captureException(error); openWalletErrorModal({ error, dataTestId: "vote-transaction-error-modal", diff --git a/govtool/frontend/src/hooks/useDelegateToDrep.ts b/govtool/frontend/src/hooks/useDelegateToDrep.ts index 179e17457..c3c57be55 100644 --- a/govtool/frontend/src/hooks/useDelegateToDrep.ts +++ b/govtool/frontend/src/hooks/useDelegateToDrep.ts @@ -1,5 +1,4 @@ import { useCallback, useState } from "react"; -import * as Sentry from "@sentry/react"; import { useCardano, useSnackbar } from "@context"; import { useGetVoterInfo, useTranslation, useWalletErrorModal } from "@hooks"; @@ -51,17 +50,12 @@ export const useDelegateTodRep = () => { resourceId: dRepId, voter, }); - } catch (error) { - console.error({ error }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (error: any) { openWalletErrorModal({ - error: - typeof error === "string" - ? error - : (error as { message: string | null })?.message, + error: error?.message ? error.message : JSON.stringify(error), dataTestId: "delegate-transaction-error-modal", }); - Sentry.setTag("hook", "useDelegateTodRep"); - Sentry.captureException(error); } finally { setIsDelegating(null); } diff --git a/govtool/frontend/src/i18n/locales/en.json b/govtool/frontend/src/i18n/locales/en.json index 75b45a80d..0b2642110 100644 --- a/govtool/frontend/src/i18n/locales/en.json +++ b/govtool/frontend/src/i18n/locales/en.json @@ -344,6 +344,8 @@ "about": "About", "abstract": "Abstract", "amount": "Amount:", + "anchorURL": "Anchor URL", + "anchorHash": "Anchor Hash", "backToGovActions": "Back to Governance Actions", "castVote": "<0>You voted {{vote}} on this proposal\non {{date}} (Epoch {{epoch}})", "castVoteDeadline": "You can change your vote up to {{date}} (Epoch {{epoch}})", @@ -361,8 +363,8 @@ "dReps": "DReps", "sPos": "SPOs", "ccCommittee": "Constitutional Committee", - "governanceActionId": "Governance Action ID:", - "cip129GovernanceActionId": "(CIP-129) Governance Action ID:", + "governanceActionId": "Legacy Governance Action ID (CIP-105):", + "cip129GovernanceActionId": "Governance Action ID:", "governanceActionType": "Governance Action Type:", "goToVote": "Go to Vote", "membersToBeRemovedFromTheCommittee": "Members to be removed from the Committee", @@ -760,6 +762,7 @@ "delegate": "Delegate", "drepId": "DRep ID", "cip129DrepId": "(CIP-129) DRep ID", + "cip105DRepId": "Legacy DRep ID (CIP-105)", "email": "Email", "feedback": "Feedback", "filter": "Filter", diff --git a/govtool/frontend/src/pages/RegisterAsDirectVoter.tsx b/govtool/frontend/src/pages/RegisterAsDirectVoter.tsx index 70df1f78f..b60bbb0c2 100644 --- a/govtool/frontend/src/pages/RegisterAsDirectVoter.tsx +++ b/govtool/frontend/src/pages/RegisterAsDirectVoter.tsx @@ -86,7 +86,7 @@ export const RegisterAsDirectVoter = () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { openWalletErrorModal({ - error, + error: error?.message ? error.message : JSON.stringify(error), buttonText: t("modals.common.goToDashboard"), onSumbit: () => navigate(PATHS.dashboard), dataTestId: "registration-transaction-error-modal", diff --git a/govtool/frontend/src/pages/RetireAsDirectVoter.tsx b/govtool/frontend/src/pages/RetireAsDirectVoter.tsx index 1b0742044..29d65bfae 100644 --- a/govtool/frontend/src/pages/RetireAsDirectVoter.tsx +++ b/govtool/frontend/src/pages/RetireAsDirectVoter.tsx @@ -61,7 +61,7 @@ export const RetireAsDirectVoter = () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { openWalletErrorModal({ - error, + error: error?.message ? error.message : JSON.stringify(error), buttonText: t("modals.common.goToDashboard"), onSumbit: () => navigate(PATHS.dashboard), dataTestId: "retirement-transaction-error-modal", diff --git a/govtool/frontend/src/stories/GovernanceActionDetailsCard.stories.ts b/govtool/frontend/src/stories/GovernanceActionDetailsCard.stories.ts index f68c39beb..c2dfda35d 100644 --- a/govtool/frontend/src/stories/GovernanceActionDetailsCard.stories.ts +++ b/govtool/frontend/src/stories/GovernanceActionDetailsCard.stories.ts @@ -42,7 +42,7 @@ const commonArgs = { expiryEpochNo: 1000001, expiryDate: new Date().toISOString(), type: GovernanceActionType.InfoAction, - url: "https://exampleurl.com", + url: "https://exampleMetadataUrl.com", title: "Example title", dRepYesVotes: 1000000, dRepNoVotes: 302, @@ -106,6 +106,13 @@ async function assertGovActionDetails( await expect(canvas.getByTestId(`${cip129GovActionId}-id`)).toHaveTextContent( cip129GovActionId, ); + + await expect(canvas.getByTestId("anchor-url")).toHaveTextContent( + args.proposal.url, + ); + await expect(canvas.getByTestId("anchor-hash")).toHaveTextContent( + args.proposal.metadataHash, + ); } export const GovernanceActionDetailsCardComponent: Story = { diff --git a/govtool/frontend/src/utils/testIdFromLabel.ts b/govtool/frontend/src/utils/testIdFromLabel.ts index 5c8c9cf4a..15beb443d 100644 --- a/govtool/frontend/src/utils/testIdFromLabel.ts +++ b/govtool/frontend/src/utils/testIdFromLabel.ts @@ -1,2 +1,2 @@ export const testIdFromLabel = (label: string) => - label.trim().replace(/ /g, "-").toLocaleLowerCase(); + label?.trim().replace(/ /g, "-").toLocaleLowerCase(); diff --git a/govtool/metadata-validation/package-lock.json b/govtool/metadata-validation/package-lock.json index dd45cdc90..fa84a6ce7 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.7", + "version": "2.0.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govtool/metadata-validation", - "version": "2.0.7", + "version": "2.0.8", "license": "UNLICENSED", "dependencies": { "@nestjs/axios": "^3.0.2", diff --git a/govtool/metadata-validation/package.json b/govtool/metadata-validation/package.json index 02901bd91..f2056ea09 100644 --- a/govtool/metadata-validation/package.json +++ b/govtool/metadata-validation/package.json @@ -1,6 +1,6 @@ { "name": "@govtool/metadata-validation", - "version": "2.0.7", + "version": "2.0.8", "description": "", "author": "", "private": true, diff --git a/govtool/metadata-validation/src/main.ts b/govtool/metadata-validation/src/main.ts index 5ba0232bc..e07b8cd42 100644 --- a/govtool/metadata-validation/src/main.ts +++ b/govtool/metadata-validation/src/main.ts @@ -13,7 +13,7 @@ async function bootstrap() { const config = new DocumentBuilder() .setTitle('Metadata Validation Tool') .setDescription('The Metadata Validation Tool API description') - .setVersion('2.0.7') + .setVersion('2.0.8') .build(); const document = SwaggerModule.createDocument(app, config); diff --git a/scripts/govtool/Makefile b/scripts/govtool/Makefile index a4c9bb4cb..b17b3b2a0 100644 --- a/scripts/govtool/Makefile +++ b/scripts/govtool/Makefile @@ -11,7 +11,7 @@ include config.mk .DEFAULT_GOAL := info # image tags -cardano_node_image_tag := 10.1.2 +cardano_node_image_tag := 10.1.4 cardano_db_sync_image_tag := 13.6.0.4 .PHONY: all diff --git a/scripts/govtool/docker-compose.node+dbsync.yml b/scripts/govtool/docker-compose.node+dbsync.yml index c88b4e037..60621b496 100644 --- a/scripts/govtool/docker-compose.node+dbsync.yml +++ b/scripts/govtool/docker-compose.node+dbsync.yml @@ -51,7 +51,7 @@ services: retries: 5 cardano-node: - image: ghcr.io/intersectmbo/cardano-node:10.1.2 + image: ghcr.io/intersectmbo/cardano-node:10.1.4 environment: - NETWORK=sanchonet volumes: