From 7eda95443874d08864c0b2aebb97a56c8afa5094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Mon, 18 Nov 2024 13:08:03 +0100 Subject: [PATCH] feat(#1600): add support for list of withdrawals in treasury gov action --- CHANGELOG.md | 1 + docs/GOVERNANCE_ACTION_SUBMISSION.md | 6 +- govtool/backend/sql/list-proposals.sql | 16 ++- ...nceActionCardTreasuryWithdrawalElement.tsx | 102 ++++++++++++++++++ .../src/components/molecules/index.ts | 1 + .../GovernanceActionDetailsCardData.tsx | 16 ++- govtool/frontend/src/context/wallet.tsx | 38 +++++-- .../forms/useCreateGovernanceActionForm.ts | 8 +- govtool/frontend/src/i18n/locales/en.json | 2 + govtool/frontend/src/theme.ts | 1 + govtool/frontend/src/types/@mui.d.ts | 1 + 11 files changed, 162 insertions(+), 30 deletions(-) create mode 100644 govtool/frontend/src/components/molecules/GovernanceActionCardTreasuryWithdrawalElement.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e2216979..7cb0d9b2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/docs/GOVERNANCE_ACTION_SUBMISSION.md b/docs/GOVERNANCE_ACTION_SUBMISSION.md index c2aa08257..140b6b0e0 100644 --- a/docs/GOVERNANCE_ACTION_SUBMISSION.md +++ b/docs/GOVERNANCE_ACTION_SUBMISSION.md @@ -41,8 +41,7 @@ interface InfoProps { interface TreasuryProps { amount: string; hash: string; - receivingAddress: string; - url: string; + withdrawals: { receivingAddress: string; amount: string }[]; } type ProtocolParamsUpdate = { @@ -184,8 +183,7 @@ const { buildTreasuryGovernanceAction } = useCardano(); const govActionBuilder = await buildTreasuryGovernanceAction({ hash, url, - amount, - receivingAddress, + withdrawals: [{ amount, receivingAddress }], }); // Protocol Parameter Change Governance Action diff --git a/govtool/backend/sql/list-proposals.sql b/govtool/backend/sql/list-proposals.sql index 7380dbcdf..2ee18431d 100644 --- a/govtool/backend/sql/list-proposals.sql +++ b/govtool/backend/sql/list-proposals.sql @@ -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) @@ -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, diff --git a/govtool/frontend/src/components/molecules/GovernanceActionCardTreasuryWithdrawalElement.tsx b/govtool/frontend/src/components/molecules/GovernanceActionCardTreasuryWithdrawalElement.tsx new file mode 100644 index 000000000..c2a1b804d --- /dev/null +++ b/govtool/frontend/src/components/molecules/GovernanceActionCardTreasuryWithdrawalElement.tsx @@ -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 ( + + + + {t("govActions.receivingAddress")} + + + + {receivingAddress} + + + + + + + + + {t("govActions.amount")} + + + ₳ {correctAdaFormat(amount) ?? 0} + + + + ); +}; diff --git a/govtool/frontend/src/components/molecules/index.ts b/govtool/frontend/src/components/molecules/index.ts index 205eff64e..89005427a 100644 --- a/govtool/frontend/src/components/molecules/index.ts +++ b/govtool/frontend/src/components/molecules/index.ts @@ -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"; diff --git a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx index a1d97ec1b..4c8afb370 100644 --- a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx +++ b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx @@ -10,6 +10,7 @@ import { GovernanceActionsDatesBox, GovernanceActionDetailsDiffView, GovernanceActionNewCommitteeDetailsTabContent, + GovernanceActionCardTreasuryWithdrawalElement, } from "@molecules"; import { useScreenDimension, useTranslation } from "@hooks"; import { @@ -20,7 +21,6 @@ import { getFullGovActionId, mapArrayToObjectByKeys, encodeCIP129Identifier, - testIdFromLabel, } from "@utils"; import { MetadataValidationStatus, @@ -297,16 +297,14 @@ export const GovernanceActionDetailsCardData = ({ ))} )} - {details && type === GovernanceActionType.TreasuryWithdrawals && - Object.keys(details).length !== 0 && - Object.entries(details).map(([detailLabel, content]) => ( - ( + ))} {details?.anchor && type === GovernanceActionType.NewConstitution && ( diff --git a/govtool/frontend/src/context/wallet.tsx b/govtool/frontend/src/context/wallet.tsx index 045b85fd1..a17b7be31 100644 --- a/govtool/frontend/src/context/wallet.tsx +++ b/govtool/frontend/src/context/wallet.tsx @@ -115,10 +115,9 @@ type InfoProps = { }; type TreasuryProps = { - amount: string; hash: string; - receivingAddress: string; url: string; + withdrawals: { receivingAddress: string; amount: string }[]; }; type ProtocolParamsUpdate = { @@ -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; diff --git a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts index 73f05ec0a..0d6e13b39 100644 --- a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts +++ b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts @@ -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); diff --git a/govtool/frontend/src/i18n/locales/en.json b/govtool/frontend/src/i18n/locales/en.json index 3577f3c18..f9faf8cbc 100644 --- a/govtool/frontend/src/i18n/locales/en.json +++ b/govtool/frontend/src/i18n/locales/en.json @@ -343,6 +343,7 @@ "govActions": { "about": "About", "abstract": "Abstract", + "amount": "Amount:", "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}})", @@ -373,6 +374,7 @@ "existing": "Existing", "proposed": "Proposed" }, + "receivingAddress": "Receiving Address:", "hardforkDetails": { "currentVersion": "Current version", "proposedVersion": "Proposed version", diff --git a/govtool/frontend/src/theme.ts b/govtool/frontend/src/theme.ts index 2d0831b23..f6ba6c6fc 100644 --- a/govtool/frontend/src/theme.ts +++ b/govtool/frontend/src/theme.ts @@ -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", diff --git a/govtool/frontend/src/types/@mui.d.ts b/govtool/frontend/src/types/@mui.d.ts index 669516950..3edb3daa3 100644 --- a/govtool/frontend/src/types/@mui.d.ts +++ b/govtool/frontend/src/types/@mui.d.ts @@ -19,6 +19,7 @@ declare module "@mui/material/styles" { arcticWhite: string; boxShadow1: string; boxShadow2: string; + darkPurple: string; errorRed: string; highlightBlue: string; inputRed: string;