Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/olive-garlics-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@aragon/app": minor
---

Implement CrossChainControllerForwardMessageAction basic action
2 changes: 1 addition & 1 deletion apps/app/config/.env.local
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# URL of the Aragon backend
ARAGON_BACKEND_URL=https://dev.backend.aragonservices.in
ARAGON_BACKEND_URL=https://sandbox.backend.aragonservices.in
Comment thread
milosh86 marked this conversation as resolved.

# Application environment
NEXT_PUBLIC_ENV=local
Expand Down
18 changes: 18 additions & 0 deletions apps/app/src/assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2519,6 +2519,24 @@
"crossChainController": {
"crossChainControllerActions": {
"CrossChainControllerForwardMessage": "Forward message"
},
"crossChainControllerForwardMessageAction": {
"actions": {
"add": "Add actions",
"edit": "Edit actions",
"emptyDescription": "Compose the actions the destination chain executes when the message is delivered.",
"emptyHeading": "No actions added",
"helpText": "These actions are executed as a single batch on the destination chain. If one of them fails, none of them are applied.",
"label": "Actions",
"selected": "{{count}} action selected",
"selectedPlural": "{{count}} actions selected"
},
"chain": {
"empty": "This cross-chain controller has no other chain configured, so there is no destination to forward a message to.",
"helpText": "The chain the message is forwarded to. Only chains configured on this cross-chain controller can be selected.",
"label": "Destination chain",
"unknown": "Chain {{chainId}}"
}
}
},
"gaugeVoter": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import type { Network } from '@/shared/api/daoService';
import type { IDialogComponentProps } from '@/shared/components/dialogProvider';
import type { IProposalActionData } from '../../components/createProposalForm';

export interface INestedActionsDialogParams {
/**
* ID of the DAO the nested actions are composed for.
*/
daoId: string;
daoId?: string;
/**
* Alternative to `daoId` if the intention is to use component outside DAO context.
*/
network?: Network;
/**
* Actions to seed the isolated dialog form with, used to edit a previously composed selection.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,17 @@ export const NestedActionsDialog: React.FC<INestedActionsDialogProps> = (
'NestedActionsDialog: required parameters must be set.',
);

const { daoId, initialActions, excludeActionTypes, onSubmit } =
const { daoId, network, initialActions, excludeActionTypes, onSubmit } =
location.params;

const { t } = useTranslations();
const { close } = useDialogContext();
const { data: dao } = useDao({ urlParams: { id: daoId } });
const { data: dao } = useDao(
{ urlParams: { id: daoId ?? '' } },
{ enabled: daoId != null },
);

const resolvedNetwork = network ?? dao?.network;

const [prepareActions, setPrepareActions] =
useState<PrepareProposalActionMap>({});
Expand Down Expand Up @@ -80,38 +85,47 @@ export const NestedActionsDialog: React.FC<INestedActionsDialogProps> = (
const hasDecodingStartedRef = useRef(false);

useEffect(() => {
if (!requiresDecoding || dao == null || hasDecodingStartedRef.current) {
if (!requiresDecoding || hasDecodingStartedRef.current) {
return;
}

if (daoId != null && dao == null) {
return;
}

hasDecodingStartedRef.current = true;

const decodeInitialActions = async () => {
try {
invariant(
resolvedNetwork != null,
'decodeInitialActions: resolvedNetwork not found',
);

const decodedActions =
await proposalActionsImportExportUtils.decodeActions(
initialActions.map(({ to, value, data }) => ({
to,
value,
data,
})),
dao.network,
resolvedNetwork,
dao,
);

// The decoder returns the backend action shape, which carries no `daoId`. Attach it
// as the composer and the action import do, since the basic views read it (e.g. a
// transfer resolves its DAO through `useDao({ id: action.daoId })`).
reset({
actions: decodedActions.map(
(action) =>
({ ...action, daoId }) as IProposalActionData,
),
actions: daoId
? decodedActions.map(
(action) =>
({ ...action, daoId }) as IProposalActionData,
)
: decodedActions,
});
} catch (error) {
monitoringUtils.logError(error, {
context: {
daoId,
network,
message: 'Failed to decode the nested proposal actions',
},
});
Expand All @@ -122,7 +136,15 @@ export const NestedActionsDialog: React.FC<INestedActionsDialogProps> = (
};

void decodeInitialActions();
}, [dao, daoId, initialActions, requiresDecoding, reset]);
}, [
dao,
daoId,
network,
resolvedNetwork,
initialActions,
requiresDecoding,
reset,
]);

const handleClose = () => close(location.id);

Expand All @@ -149,6 +171,7 @@ export const NestedActionsDialog: React.FC<INestedActionsDialogProps> = (
monitoringUtils.logError(error, {
context: {
daoId,
network,
message: 'Failed to prepare the nested proposal actions',
},
});
Expand All @@ -158,7 +181,6 @@ export const NestedActionsDialog: React.FC<INestedActionsDialogProps> = (
}
};

// TODO: enable running without DAO ID
return (
<FormProvider {...methods}>
<CreateProposalFormProvider value={contextValues}>
Expand All @@ -181,6 +203,7 @@ export const NestedActionsDialog: React.FC<INestedActionsDialogProps> = (
<ProposalActionsEditor
daoId={daoId}
excludeActionTypes={excludeActionTypes}
network={network}
/>
)}
{hasDecodeError && (
Expand Down
Loading
Loading