Skip to content

Commit eaf0ed5

Browse files
committed
feat(#2258): add support for submitting new governance actions inside wrapper
1 parent c9c419b commit eaf0ed5

File tree

6 files changed

+312
-54
lines changed

6 files changed

+312
-54
lines changed

govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/CreateGovernanceActionForm.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ export const CreateGovernanceActionForm = ({
4747
type! as
4848
| GovernanceActionType.InfoAction
4949
| GovernanceActionType.TreasuryWithdrawals
50+
| GovernanceActionType.NewCommittee
51+
| GovernanceActionType.NewConstitution
52+
| GovernanceActionType.NoConfidence
5053
],
5154
).some(
5255
(field) => !watch(field as unknown as Parameters<typeof watch>[0]),
@@ -67,6 +70,9 @@ export const CreateGovernanceActionForm = ({
6770
type! as
6871
| GovernanceActionType.InfoAction
6972
| GovernanceActionType.TreasuryWithdrawals
73+
| GovernanceActionType.NewCommittee
74+
| GovernanceActionType.NewConstitution
75+
| GovernanceActionType.NoConfidence
7076
],
7177
).map(([key, field]) => {
7278
const fieldProps = {

govtool/frontend/src/consts/governanceAction/fields.ts

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,92 @@ export const sharedGovernanceActionFields: SharedGovernanceActionFieldSchema = {
9797

9898
export const GOVERNANCE_ACTION_FIELDS: GovernanceActionFields = {
9999
[GovernanceActionType.InfoAction]: sharedGovernanceActionFields,
100+
[GovernanceActionType.NoConfidence]: sharedGovernanceActionFields,
101+
[GovernanceActionType.NewCommittee]: {
102+
...sharedGovernanceActionFields,
103+
numerator: {
104+
component: GovernanceActionField.Input,
105+
labelI18nKey:
106+
"createGovernanceAction.fields.declarations.numerator.label",
107+
placeholderI18nKey:
108+
"createGovernanceAction.fields.declarations.numerator.placeholder",
109+
rules: {
110+
required: {
111+
value: true,
112+
message: I18n.t("createGovernanceAction.fields.validations.required"),
113+
},
114+
validate: numberValidation,
115+
},
116+
},
117+
denominator: {
118+
component: GovernanceActionField.Input,
119+
labelI18nKey:
120+
"createGovernanceAction.fields.declarations.denominator.label",
121+
placeholderI18nKey:
122+
"createGovernanceAction.fields.declarations.denominator.placeholder",
123+
rules: {
124+
required: {
125+
value: true,
126+
message: I18n.t("createGovernanceAction.fields.validations.required"),
127+
},
128+
validate: numberValidation,
129+
},
130+
},
131+
newCommitteeHash: {
132+
component: GovernanceActionField.Input,
133+
labelI18nKey: "createGovernanceAction.fields.declarations.members.label",
134+
placeholderI18nKey:
135+
"createGovernanceAction.fields.declarations.members.placeholder",
136+
tipI18nKey: "createGovernanceAction.fields.declarations.members.tip",
137+
rules: {
138+
required: {
139+
value: true,
140+
message: I18n.t("createGovernanceAction.fields.validations.required"),
141+
},
142+
maxLength: {
143+
value: 500,
144+
message: I18n.t(
145+
"createGovernanceAction.fields.validations.maxLength",
146+
{
147+
maxLength: 500,
148+
},
149+
),
150+
},
151+
},
152+
},
153+
newCommitteeExpiryEpoch: {
154+
component: GovernanceActionField.Input,
155+
labelI18nKey:
156+
"createGovernanceAction.fields.declarations.expiryEpoch.label",
157+
placeholderI18nKey:
158+
"createGovernanceAction.fields.declarations.expiryEpoch.placeholder",
159+
rules: {
160+
required: {
161+
value: true,
162+
message: I18n.t("createGovernanceAction.fields.validations.required"),
163+
},
164+
validate: numberValidation,
165+
},
166+
},
167+
removeCommitteeHash: {
168+
component: GovernanceActionField.Input,
169+
labelI18nKey: "createGovernanceAction.fields.declarations.remove.label",
170+
placeholderI18nKey:
171+
"createGovernanceAction.fields.declarations.remove.placeholder",
172+
tipI18nKey: "createGovernanceAction.fields.declarations.remove.tip",
173+
rules: {
174+
maxLength: {
175+
value: 500,
176+
message: I18n.t(
177+
"createGovernanceAction.fields.validations.maxLength",
178+
{
179+
maxLength: 500,
180+
},
181+
),
182+
},
183+
},
184+
},
185+
},
100186
[GovernanceActionType.TreasuryWithdrawals]: {
101187
...sharedGovernanceActionFields,
102188
receivingAddress: {
@@ -123,6 +209,59 @@ export const GOVERNANCE_ACTION_FIELDS: GovernanceActionFields = {
123209
},
124210
},
125211
},
212+
[GovernanceActionType.NewConstitution]: {
213+
...sharedGovernanceActionFields,
214+
prevGovernanceActionHash: {
215+
component: GovernanceActionField.Input,
216+
labelI18nKey:
217+
"createGovernanceAction.fields.declarations.prevGovernanceActionHash.label",
218+
placeholderI18nKey:
219+
"createGovernanceAction.fields.declarations.prevGovernanceActionHash.placeholder",
220+
},
221+
prevGovernanceActionIndex: {
222+
component: GovernanceActionField.Input,
223+
labelI18nKey:
224+
"createGovernanceAction.fields.declarations.prevGovernanceActionIndex.label",
225+
placeholderI18nKey:
226+
"createGovernanceAction.fields.declarations.prevGovernanceActionIndex.placeholder",
227+
rules: {
228+
validate: numberValidation,
229+
},
230+
},
231+
constitutionUrl: {
232+
component: GovernanceActionField.Input,
233+
labelI18nKey:
234+
"createGovernanceAction.fields.declarations.constitutionUrl.label",
235+
placeholderI18nKey:
236+
"createGovernanceAction.fields.declarations.constitutionUrl.placeholder",
237+
rules: {
238+
required: {
239+
value: true,
240+
message: I18n.t("createGovernanceAction.fields.validations.required"),
241+
},
242+
},
243+
},
244+
constitutionHash: {
245+
component: GovernanceActionField.Input,
246+
labelI18nKey:
247+
"createGovernanceAction.fields.declarations.constitutionHash.label",
248+
placeholderI18nKey:
249+
"createGovernanceAction.fields.declarations.constitutionHash.placeholder",
250+
rules: {
251+
required: {
252+
value: true,
253+
message: I18n.t("createGovernanceAction.fields.validations.required"),
254+
},
255+
},
256+
},
257+
scriptHash: {
258+
component: GovernanceActionField.Input,
259+
labelI18nKey:
260+
"createGovernanceAction.fields.declarations.scriptHash.label",
261+
placeholderI18nKey:
262+
"createGovernanceAction.fields.declarations.scriptHash.placeholder",
263+
},
264+
},
126265
} as const;
127266

128267
export const GOVERNANCE_ACTION_CONTEXT = {

govtool/frontend/src/context/wallet.tsx

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -136,35 +136,35 @@ type ProtocolParameterChangeProps = {
136136

137137
type HardForkInitiationProps = {
138138
prevGovernanceActionHash: string;
139-
prevGovernanceActionIndex: number;
140-
major: number;
141-
minor: number;
139+
prevGovernanceActionIndex: string;
140+
major: string;
141+
minor: string;
142142
} & VotingAnchor;
143143

144144
type NewConstitutionProps = {
145-
prevGovernanceActionHash: string;
146-
prevGovernanceActionIndex: number;
145+
prevGovernanceActionHash?: string;
146+
prevGovernanceActionIndex?: string;
147147
constitutionUrl: string;
148148
constitutionHash: string;
149-
scriptHash: string;
149+
scriptHash?: string;
150150
} & VotingAnchor;
151151

152152
type UpdateCommitteeProps = {
153153
prevGovernanceActionHash?: string;
154-
prevGovernanceActionIndex?: number;
154+
prevGovernanceActionIndex?: string;
155155
quorumThreshold: QuorumThreshold;
156156
newCommittee?: CommitteeToAdd[];
157157
removeCommittee?: string[];
158158
} & VotingAnchor;
159159

160160
export type CommitteeToAdd = {
161-
expiryEpoch: number;
161+
expiryEpoch: string;
162162
committee: string;
163163
};
164164

165165
export type QuorumThreshold = {
166-
numerator: number;
167-
denominator: number;
166+
numerator: string;
167+
denominator: string;
168168
};
169169

170170
type ProtocolParamsUpdate = {
@@ -1060,7 +1060,7 @@ const CardanoProvider = (props: Props) => {
10601060
if (prevGovernanceActionHash && prevGovernanceActionIndex) {
10611061
const prevGovernanceActionId = GovernanceActionId.new(
10621062
TransactionHash.from_hex(prevGovernanceActionHash),
1063-
prevGovernanceActionIndex,
1063+
Number(prevGovernanceActionIndex),
10641064
);
10651065
newConstitution = NewConstitutionAction.new_with_action_id(
10661066
prevGovernanceActionId,
@@ -1112,14 +1112,13 @@ const CardanoProvider = (props: Props) => {
11121112
BigNum.from_str(quorumThreshold.numerator.toString()),
11131113
BigNum.from_str(quorumThreshold.denominator.toString()),
11141114
);
1115-
11161115
const committeeToAdd = Committee.new(threshold);
11171116
if (newCommittee) {
11181117
newCommittee.forEach(async (member) => {
11191118
const credential = await buildCredentialFromBech32Key(
11201119
member.committee,
11211120
);
1122-
committeeToAdd.add_member(credential, member.expiryEpoch);
1121+
committeeToAdd.add_member(credential, Number(member.expiryEpoch));
11231122
});
11241123
}
11251124
const committeeToRemoveCredentials = Credentials.new();
@@ -1134,7 +1133,7 @@ const CardanoProvider = (props: Props) => {
11341133
if (prevGovernanceActionHash && prevGovernanceActionIndex) {
11351134
const prevGovernanceActionId = GovernanceActionId.new(
11361135
TransactionHash.from_hex(prevGovernanceActionHash),
1137-
prevGovernanceActionIndex,
1136+
Number(prevGovernanceActionIndex),
11381137
);
11391138
updateCommitteeAction = UpdateCommitteeAction.new_with_action_id(
11401139
prevGovernanceActionId,
@@ -1393,13 +1392,16 @@ const CardanoProvider = (props: Props) => {
13931392
}: HardForkInitiationProps) => {
13941393
const govActionBuilder = VotingProposalBuilder.new();
13951394
try {
1396-
const newProtocolVersion = ProtocolVersion.new(major, minor);
1395+
const newProtocolVersion = ProtocolVersion.new(
1396+
Number(major),
1397+
Number(minor),
1398+
);
13971399

13981400
let hardForkInitiationAction;
13991401
if (prevGovernanceActionHash && prevGovernanceActionIndex) {
14001402
const prevGovernanceActionId = GovernanceActionId.new(
14011403
TransactionHash.from_hex(prevGovernanceActionHash),
1402-
prevGovernanceActionIndex,
1404+
Number(prevGovernanceActionIndex),
14031405
);
14041406
hardForkInitiationAction =
14051407
HardForkInitiationAction.new_with_action_id(

govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
PATHS,
1111
storageInformationErrorModals,
1212
} from "@consts";
13-
import { useCardano, useModal, useAppContext } from "@context";
13+
import { useCardano, useModal, useAppContext, QuorumThreshold } from "@context";
1414
import {
1515
correctAdaFormat,
1616
downloadJson,
@@ -56,6 +56,9 @@ export const useCreateGovernanceActionForm = (
5656
const {
5757
buildNewInfoGovernanceAction,
5858
buildTreasuryGovernanceAction,
59+
buildNoConfidenceGovernanceAction,
60+
buildNewConstitutionGovernanceAction,
61+
buildUpdateCommitteeGovernanceAction,
5962
buildSignSubmitConwayCertTx,
6063
} = useCardano();
6164

@@ -131,6 +134,64 @@ export const useCreateGovernanceActionForm = (
131134
switch (govActionType) {
132135
case GovernanceActionType.InfoAction:
133136
return buildNewInfoGovernanceAction(commonGovActionDetails);
137+
case GovernanceActionType.NoConfidence:
138+
return buildNoConfidenceGovernanceAction(commonGovActionDetails);
139+
case GovernanceActionType.NewConstitution: {
140+
if (
141+
data.constitutionUrl === undefined ||
142+
data.constitutionHash === undefined
143+
) {
144+
throw new Error(
145+
t("errors.invalidNewCommitteeGovernanceActionType"),
146+
);
147+
}
148+
149+
return buildNewConstitutionGovernanceAction({
150+
...commonGovActionDetails,
151+
constitutionUrl: data.constitutionUrl,
152+
constitutionHash: data.constitutionHash,
153+
scriptHash: data.scriptHash,
154+
prevGovernanceActionHash: data.prevGovernanceActionHash,
155+
prevGovernanceActionIndex: data.prevGovernanceActionIndex,
156+
});
157+
}
158+
case GovernanceActionType.NewCommittee: {
159+
if (
160+
data.newCommitteeHash === undefined ||
161+
data.newCommitteeExpiryEpoch === undefined
162+
) {
163+
throw new Error(
164+
t("errors.invalidUpdateCommitteeGovernanceActionType"),
165+
);
166+
}
167+
168+
let quorumThreshold: QuorumThreshold = {
169+
numerator: "1",
170+
denominator: "2",
171+
};
172+
if (data.numerator !== undefined && data.denominator !== undefined) {
173+
quorumThreshold = {
174+
numerator: data.numerator,
175+
denominator: data.denominator,
176+
};
177+
}
178+
179+
return buildUpdateCommitteeGovernanceAction({
180+
...commonGovActionDetails,
181+
newCommittee: [
182+
{
183+
committee: data.newCommitteeHash,
184+
expiryEpoch: data.newCommitteeExpiryEpoch,
185+
},
186+
],
187+
removeCommittee: data.removeCommitteeHash
188+
? [data.removeCommitteeHash]
189+
: [],
190+
quorumThreshold,
191+
prevGovernanceActionHash: data.prevGovernanceActionHash,
192+
prevGovernanceActionIndex: data.prevGovernanceActionIndex,
193+
});
194+
}
134195
case GovernanceActionType.TreasuryWithdrawals: {
135196
if (
136197
data.amount === undefined ||

0 commit comments

Comments
 (0)