Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ changes.
### Added

- Preserve maintenance ending banner state on the wallet connection change [Issue 3681](https://github.com/IntersectMBO/govtool/issues/3681)
- Add authors for Live Voting Governance Actions [Issue 3745](https://github.com/IntersectMBO/govtool/issues/3745)

### Fixed

Expand Down
14 changes: 13 additions & 1 deletion govtool/backend/sql/list-proposals.sql
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,18 @@ SELECT
COALESCE(cv.ccNoVotes, 0) cc_no_votes,
COALESCE(cv.ccAbstainVotes, 0) cc_abstain_votes,
prev_gov_action.index as prev_gov_action_index,
encode(prev_gov_action_tx.hash, 'hex') as prev_gov_action_tx_hash
encode(prev_gov_action_tx.hash, 'hex') as prev_gov_action_tx_hash,
COALESCE(
json_agg(
json_build_object(
'name', off_chain_vote_author.name,
'witness_algorithm', off_chain_vote_author.witness_algorithm,
'public_key', off_chain_vote_author.public_key,
'signature', off_chain_vote_author.signature
)
) FILTER (WHERE off_chain_vote_author.id IS NOT NULL),
'[]'
) authors
FROM
gov_action_proposal
JOIN ActiveProposals ON gov_action_proposal.id = ActiveProposals.id
Expand All @@ -314,6 +325,7 @@ FROM
LEFT JOIN block AS creator_block ON creator_block.id = creator_tx.block_id
LEFT JOIN voting_anchor ON voting_anchor.id = gov_action_proposal.voting_anchor_id
LEFT JOIN off_chain_vote_data ON off_chain_vote_data.voting_anchor_id = voting_anchor.id
lEFT JOIN off_chain_vote_author ON off_chain_vote_author.off_chain_vote_data_id = off_chain_vote_data.id
LEFT JOIN off_chain_vote_gov_action_data ON off_chain_vote_gov_action_data.off_chain_vote_data_id = off_chain_vote_data.id
LEFT JOIN param_proposal AS proposal_params ON gov_action_proposal.param_proposal = proposal_params.id
LEFT JOIN cost_model AS cost_model ON proposal_params.cost_model_id = cost_model.id
Expand Down
3 changes: 2 additions & 1 deletion govtool/backend/src/VVA/API.hs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ proposalToResponse timeZone Types.Proposal {..} =
proposalResponseCcNoVotes = proposalCcNoVotes,
proposalResponseCcAbstainVotes = proposalCcAbstainVotes,
proposalResponsePrevGovActionIndex = proposalPrevGovActionIndex,
proposalResponsePrevGovActionTxHash = HexText <$> proposalPrevGovActionTxHash
proposalResponsePrevGovActionTxHash = HexText <$> proposalPrevGovActionTxHash,
proposalResponseAuthors = ProposalAuthors <$> proposalAuthors
}

voteToResponse :: Types.Vote -> VoteParams
Expand Down
30 changes: 30 additions & 0 deletions govtool/backend/src/VVA/API/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,39 @@ data ProposalResponse
, proposalResponseCcAbstainVotes :: Integer
, proposalResponsePrevGovActionIndex :: Maybe Integer
, proposalResponsePrevGovActionTxHash :: Maybe HexText
, proposalResponseAuthors :: Maybe ProposalAuthors
}
deriving (Generic, Show)

newtype ProposalAuthors = ProposalAuthors { getProposalAuthors :: Value }
deriving newtype (Show)

instance FromJSON ProposalAuthors where
parseJSON v@(Array _) = pure $ ProposalAuthors v
parseJSON _ = fail "ProposalAuthors must be a JSON array"

instance ToJSON ProposalAuthors where
toJSON (ProposalAuthors v) = v

instance ToSchema ProposalAuthors where
declareNamedSchema _ = pure $ NamedSchema (Just "ProposalAuthors") $ mempty
& type_ ?~ OpenApiArray
& description ?~ "A JSON array of proposal authors"
& example ?~ toJSON
[ object
[ "name" .= ("Alice" :: Text)
, "witness_algorithm" .= ("algo" :: Text)
, "public_key" .= ("key" :: Text)
, "signature" .= ("sig" :: Text)
]
, object
[ "name" .= ("Bob" :: Text)
, "witness_algorithm" .= ("algo2" :: Text)
, "public_key" .= ("key2" :: Text)
, "signature" .= ("sig2" :: Text)
]
]

deriveJSON (jsonOptions "proposalResponse") ''ProposalResponse

exampleProposalResponse :: Text
Expand Down
2 changes: 2 additions & 0 deletions govtool/backend/src/VVA/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ data Proposal
, proposalCcAbstainVotes :: Integer
, proposalPrevGovActionIndex :: Maybe Integer
, proposalPrevGovActionTxHash :: Maybe Text
, proposalAuthors :: Maybe Value
}
deriving (Show)

Expand Down Expand Up @@ -241,6 +242,7 @@ instance FromRow Proposal where
<*> (floor @Scientific <$> field) -- proposalCcAbstainVotes
<*> field -- prevGovActionIndex
<*> field -- prevGovActionTxHash
<*> field -- proposalAuthors

data TransactionStatus = TransactionStatus
{ transactionConfirmed :: Bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useModal } from "@/context";

type BaseProps = {
label: string;
text?: string | number;
text?: React.ReactNode;
dataTestId?: string;
isSliderCard?: boolean;
tooltipProps?: Omit<TooltipProps, "children">;
Expand Down Expand Up @@ -108,7 +108,7 @@ export const GovernanceActionCardElement = ({
...(isSemiTransparent && { opacity: 0.75 }),
}}
>
{isMarkdown ? removeMarkdown(text) : text}
{typeof text === "string" && isMarkdown ? removeMarkdown(text) : text}
</Typography>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useMemo, useState } from "react";
import { useMemo, useState, Fragment } from "react";
import { Box, Tabs, Tab, styled, Skeleton } from "@mui/material";
import { useLocation } from "react-router-dom";

import { CopyButton, ExternalModalButton, Typography } from "@atoms";
import { CopyButton, ExternalModalButton, Tooltip, Typography } from "@atoms";
import {
GovernanceActionCardElement,
GovernanceActionDetailsCardLinks,
Expand Down Expand Up @@ -76,6 +76,7 @@ export const GovernanceActionDetailsCardData = ({
isValidating,
proposal: {
abstract,
authors,
createdDate,
createdEpochNo,
details,
Expand Down Expand Up @@ -365,6 +366,35 @@ export const GovernanceActionDetailsCardData = ({
/>
</>
)}
<GovernanceActionCardElement
label={t("govActions.authors.title")}
text={
(authors ?? []).length <= 0
? t("govActions.authors.noDataAvailable")
: (authors ?? []).map((author, idx, arr) => (
<Fragment key={author.publicKey}>
<Tooltip
heading={`${t("govActions.authors.witnessAlgorithm")}: ${
author.witnessAlgorithm
}`}
paragraphOne={`${t("govActions.authors.publicKey")}: ${
author.publicKey
}`}
paragraphTwo={`${t("govActions.authors.signature")}: ${
author.signature
}`}
placement="bottom-end"
arrow
>
<span>{author.name}</span>
</Tooltip>
{idx < arr.length - 1 && <span>,&nbsp;</span>}
</Fragment>
))
}
textVariant="longText"
dataTestId="authors"
/>

<GovernanceActionDetailsCardLinks links={references} />
</Box>
Expand Down
7 changes: 7 additions & 0 deletions govtool/frontend/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,13 @@
"amount": "Amount:",
"anchorURL": "Metadata anchor link",
"anchorHash": "Metadata anchor hash",
"authors": {
"noDataAvailable": "No data available",
"title": "Authors",
"publicKey": "Public Key",
"signature": "Signature",
"witnessAlgorithm": "Witness Algorithm"
},
"backToGovActions": "Back to Governance Actions",
"castVote": "<0>You voted {{vote}} on this proposal</0>\non {{date}} (Epoch {{epoch}})",
"castVoteDeadline": "You can change your vote up to {{date}} (Epoch {{epoch}})",
Expand Down
16 changes: 11 additions & 5 deletions govtool/frontend/src/models/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ export type ProposalData = {
references?: Reference[];
title?: string;
protocolParams: EpochParams | null;
authors?: {
name?: string;
witnessAlgorithm?: string;
publicKey?: string;
signature?: string;
}[];
} & SubmittedVotesData;

export type NewConstitutionAnchor = {
Expand Down Expand Up @@ -270,8 +276,8 @@ type DRepVotingPower = {
export type DRepVotingPowerListResponse = DRepVotingPower[];

export type Account = {
id: number,
view: string,
isRegistered: boolean,
isScriptBased: boolean
}
id: number;
view: string;
isRegistered: boolean;
isScriptBased: boolean;
};
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ const commonArgs = {
label: "Example label",
},
],
authors: [
{
name: "Alice Cardana",
witnessAlgorithm: "Ed25519",
publicKey: "ed25519_pk1qwertyuiopasdfghjklzxcvbnm1234567890abcdef",
signature: "ed25519_sig1abcdef1234567890qwertyuiopasdfghjklzxcvbnm",
},
{
name: "Bob Stakepool",
witnessAlgorithm: "Ed25519",
publicKey: "ed25519_pk1asdfghjklqwertyuiopzxcvbnm0987654321abcdf",
signature: "ed25519_sig1zxcvbnm0987654321asdfghjklqwertyuiop",
},
],
} satisfies ProposalData,
};

Expand Down