Skip to content

Commit

Permalink
feat(#1600): add support for list of withdrawals in treasury gov action
Browse files Browse the repository at this point in the history
  • Loading branch information
MSzalowski committed Nov 18, 2024
1 parent ac6ba3d commit 7eda954
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ changes.
- Add support for displaying Update committee/threshold Governance Action [Issue 1598](https://github.com/IntersectMBO/govtool/issues/1598)
- Add support for displaying New Constitution and/or Guardrails Script Governance Action [Issue 1599](https://github.com/IntersectMBO/govtool/issues/1598)
- Add support for ipfs in metadata validation service [Issue 1616](https://github.com/IntersectMBO/govtool/issues/1616)
- Add support for displaying array of treasury withdrawals [Issue 1602](https://github.com/IntersectMBO/govtool/issues/1602)

### Fixed

Expand Down
6 changes: 2 additions & 4 deletions docs/GOVERNANCE_ACTION_SUBMISSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ interface InfoProps {
interface TreasuryProps {
amount: string;
hash: string;
receivingAddress: string;
url: string;
withdrawals: { receivingAddress: string; amount: string }[];
}

type ProtocolParamsUpdate = {
Expand Down Expand Up @@ -184,8 +183,7 @@ const { buildTreasuryGovernanceAction } = useCardano();
const govActionBuilder = await buildTreasuryGovernanceAction({
hash,
url,
amount,
receivingAddress,
withdrawals: [{ amount, receivingAddress }],
});

// Protocol Parameter Change Governance Action
Expand Down
16 changes: 12 additions & 4 deletions govtool/backend/sql/list-proposals.sql
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,18 @@ SELECT
gov_action_proposal.type::text,
(
case when gov_action_proposal.type = 'TreasuryWithdrawals' then
json_build_object('Reward Address', stake_address.view, 'Amount', treasury_withdrawal.amount)

(
select json_agg(
jsonb_build_object(
'receivingAddress', stake_address.view,
'amount', treasury_withdrawal.amount
)
)
from treasury_withdrawal
left join stake_address
on stake_address.id = treasury_withdrawal.stake_address_id
where treasury_withdrawal.gov_action_proposal_id = gov_action_proposal.id
)
when gov_action_proposal.type::text = 'InfoAction' then
json_build_object('data', gov_action_proposal.description)

Expand Down Expand Up @@ -261,8 +271,6 @@ AND gov_action_proposal.expired_epoch IS NULL
AND gov_action_proposal.dropped_epoch IS NULL
GROUP BY
(gov_action_proposal.id,
stake_address.view,
treasury_withdrawal.amount,
creator_block.epoch_no,
off_chain_vote_gov_action_data.title,
off_chain_vote_gov_action_data.abstract,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { Box } from "@mui/material";
import { useTranslation } from "react-i18next";

import { Typography, CopyButton } from "@atoms";
import { correctAdaFormat } from "@utils";

import { useScreenDimension } from "@/hooks";

type Props = {
receivingAddress: string;
amount: number;
};

export const GovernanceActionCardTreasuryWithdrawalElement = ({
receivingAddress,
amount,
}: Props) => {
const { t } = useTranslation();
const { isMobile } = useScreenDimension();
return (
<Box
sx={{
display: "flex",
mb: "4px",
flexDirection: "column",
}}
>
<Box sx={{ display: "flex", flexDirection: isMobile ? "column" : "row" }}>
<Typography
data-testid="receiving-address-label"
sx={{
width: "160px",
fontSize: 14,
fontWeight: 600,
lineHeight: "20px",
color: "neutralGray",
}}
>
{t("govActions.receivingAddress")}
</Typography>
<Box
sx={{
display: "flex",
alignItems: "center",
overflow: "hidden",
flexDirection: "row",
}}
>
<Typography
data-testid="receiving-address"
sx={{
ml: isMobile ? 0 : 8,
color: "primaryBlue",
fontSize: 16,
fontWeight: 400,
lineHeight: "20px",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
{receivingAddress}
</Typography>
<Box ml={1}>
<CopyButton text={receivingAddress} variant="blueThin" />
</Box>
</Box>
</Box>
<Box
sx={{
display: "flex",
flexDirection: isMobile ? "column" : "row",
mt: "6px",
}}
>
<Typography
sx={{
width: "160px",
fontSize: 14,
fontWeight: 600,
lineHeight: "20px",
color: "neutralGray",
}}
data-testid="amount-label"
>
{t("govActions.amount")}
</Typography>
<Typography
data-testid="amount"
sx={{
ml: isMobile ? 0 : 8,
fontSize: 16,
fontWeight: 400,
lineHeight: "20px",
}}
>
{correctAdaFormat(amount) ?? 0}
</Typography>
</Box>
</Box>
);
};
1 change: 1 addition & 0 deletions govtool/frontend/src/components/molecules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export * from "./GovernanceActionCardElement";
export * from "./GovernanceActionCardHeader";
export * from "./GovernanceActionCardMyVote";
export * from "./GovernanceActionCardStatePill";
export * from "./GovernanceActionCardTreasuryWithdrawalElement";
export * from "./GovernanceActionDetailsCardLinks";
export * from "./GovernanceActionDetailsCardOnChainData";
export * from "./GovernanceActionDetailsCardVotes";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
GovernanceActionsDatesBox,
GovernanceActionDetailsDiffView,
GovernanceActionNewCommitteeDetailsTabContent,
GovernanceActionCardTreasuryWithdrawalElement,
} from "@molecules";
import { useScreenDimension, useTranslation } from "@hooks";
import {
Expand All @@ -20,7 +21,6 @@ import {
getFullGovActionId,
mapArrayToObjectByKeys,
encodeCIP129Identifier,
testIdFromLabel,
} from "@utils";
import {
MetadataValidationStatus,
Expand Down Expand Up @@ -297,16 +297,14 @@ export const GovernanceActionDetailsCardData = ({
))}
</>
)}

{details &&
type === GovernanceActionType.TreasuryWithdrawals &&
Object.keys(details).length !== 0 &&
Object.entries(details).map(([detailLabel, content]) => (
<GovernanceActionCardElement
isCopyButton={detailLabel.toLowerCase().includes("address")}
label={detailLabel}
text={content as string}
dataTestId={testIdFromLabel(detailLabel)}
Array.isArray(details) &&
details.map((withdrawal) => (
<GovernanceActionCardTreasuryWithdrawalElement
key={withdrawal.receivingAddress}
receivingAddress={withdrawal.receivingAddress}
amount={withdrawal.amount}
/>
))}
{details?.anchor && type === GovernanceActionType.NewConstitution && (
Expand Down
38 changes: 27 additions & 11 deletions govtool/frontend/src/context/wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,9 @@ type InfoProps = {
};

type TreasuryProps = {
amount: string;
hash: string;
receivingAddress: string;
url: string;
withdrawals: { receivingAddress: string; amount: string }[];
};

type ProtocolParamsUpdate = {
Expand Down Expand Up @@ -1011,23 +1010,40 @@ const CardanoProvider = (props: Props) => {

// treasury action
const buildTreasuryGovernanceAction = useCallback(
async ({ amount, hash, receivingAddress, url }: TreasuryProps) => {
async ({ hash, url, withdrawals }: TreasuryProps) => {
const govActionBuilder = VotingProposalBuilder.new();
try {
const treasuryTarget = RewardAddress.from_address(
Address.from_bech32(receivingAddress),
);
const mappedWithdrawals: {
treasuryTarget: RewardAddress;
amount: BigNum;
}[] = [];

withdrawals.forEach((withdrawal) => {
const treasuryTarget = RewardAddress.from_address(
Address.from_bech32(withdrawal.receivingAddress),
);

if (!treasuryTarget) throw new Error("Can not get tresasury target");
if (!treasuryTarget)
throw new Error(
`Can not get tresasury target for address: ${withdrawal.receivingAddress}`,
);

const myWithdrawal = BigNum.from_str(amount);
const withdrawals = TreasuryWithdrawals.new();
withdrawals.insert(treasuryTarget, myWithdrawal);
const amount = BigNum.from_str(withdrawal.amount);
mappedWithdrawals.push({ treasuryTarget, amount });
});

const treasuryWithdrawals = TreasuryWithdrawals.new();
mappedWithdrawals.forEach((withdrawal) => {
treasuryWithdrawals.insert(
withdrawal.treasuryTarget,
withdrawal.amount,
);
});
const guardrailPlutusScript = PlutusScript.from_bytes_v3(
Buffer.from(guardrailScript, "hex"),
);
const treasuryAction = TreasuryWithdrawalsAction.new_with_policy_hash(
withdrawals,
treasuryWithdrawals,
guardrailPlutusScript.hash(),
);
isGuardrailScriptUsed.current = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,12 @@ export const useCreateGovernanceActionForm = (

const treasuryActionDetails = {
...commonGovActionDetails,
amount: data.amount,
receivingAddress: data.receivingAddress,
withdrawals: [
{
amount: data.amount,
receivingAddress: data.receivingAddress,
},
],
};

return await buildTreasuryGovernanceAction(treasuryActionDetails);
Expand Down
2 changes: 2 additions & 0 deletions govtool/frontend/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@
"govActions": {
"about": "About",
"abstract": "Abstract",
"amount": "Amount:",
"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 Expand Up @@ -373,6 +374,7 @@
"existing": "Existing",
"proposed": "Proposed"
},
"receivingAddress": "Receiving Address:",
"hardforkDetails": {
"currentVersion": "Current version",
"proposedVersion": "Proposed version",
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export const theme = createTheme({
arcticWhite: "#FBFBFF",
boxShadow1: "rgba(0, 18, 61, 0.37)",
boxShadow2: "rgba(47, 98, 220, 0.2)",
darkPurple: "rgba(36, 34, 50, 1)",
errorRed: "#9E2323",
fadedPurple: "#716E88",
highlightBlue: "#C2EFF299",
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/types/@mui.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ declare module "@mui/material/styles" {
arcticWhite: string;
boxShadow1: string;
boxShadow2: string;
darkPurple: string;
errorRed: string;
highlightBlue: string;
inputRed: string;
Expand Down

0 comments on commit 7eda954

Please sign in to comment.