diff --git a/packages/i18n/locales/en/translation.json b/packages/i18n/locales/en/translation.json index 0ae5c0743..7c72d117c 100644 --- a/packages/i18n/locales/en/translation.json +++ b/packages/i18n/locales/en/translation.json @@ -32,6 +32,8 @@ "rebalancerLabel": "Rebalancer", "smartContractingDescription": "Create, execute, and manage smart contracts.", "smartContractingLabel": "Smart Contracting", + "subDaosDescription": "Manage SubDAOs or become a SubDAO.", + "subDaosLabel": "SubDAOs", "treasuryDescription_dao": "Manage this DAO's treasury (for example, send payments, stake or swap tokens, etc.).", "treasuryDescription_gov": "Manage the community pool (for example, send payments, stake or swap tokens, etc.).", "treasuryDescription_wallet": "Manage your tokens (for example, send payments, stake or swap tokens, etc.).", @@ -315,6 +317,7 @@ "cameraWithFlash": "Camera with flash", "chains": "Chains", "chart": "Chart", + "check": "Check", "clock": "Clock", "closedLockWithKey": "Closed lock with key", "computerDisk": "Computer disk", @@ -537,6 +540,7 @@ "unsupportedWallet": "Unsupported wallet. Please use a different wallet." }, "form": { + "acceptSubDaoAddressInputLabel": "SubDAO to accept", "addAnImage": "Add an image", "address": "Address", "addressInputPlaceholder_any": "Search profile or DAO name or enter an address...", @@ -567,6 +571,7 @@ "automaticallyAddTokensTitle": "Automatically add tokens", "automaticallyAddTokensTooltip": "Should tokens sent to the DAO get added to the treasury?", "baseToken": "Base token", + "becomeSubDaoAdminInputLabel": "New parent DAO", "blocksToPauseFor": "Blocks to pause for", "buttonLabel": "Button label", "calls": "Calls", @@ -895,6 +900,9 @@ }, "info": { "abstainVote": "Abstain", + "acceptSubDaoActionDescription": "Accept a pending SubDAO's ownership transfer request. Be sure that the SubDAO-to-be has already requested to join your DAO through the \"Become SubDAO\" action.", + "acceptSubDaoActionOtherActionsAdded": "Other actions that are required to register a new SubDAO have been added to the proposal automatically.", + "acceptSubDaoDescription": "Accept a DAO's request to become a SubDAO.", "acknowledgeServiceFee": "We acknowledge that {{fee}} will be charged from the treasury for registration to the rebalancer.", "acknowledgeServiceFee_none": "We acknowledge that there is no fee to register for the rebalancer.", "actionLibraryDescription": "Choose one or more actions to perform upon execution.", @@ -944,6 +952,9 @@ "available": "available", "availableBalance": "Available balance", "availableHistoryLoaded": "All available history has been loaded.", + "becomeSubDaoActionDescription": "Provide the address of a DAO to request to become its SubDAO. The DAO will then need to accept your request to complete the ownership transfer and become your parent. Once the transfer is complete, only your new parent DAO can transfer ownership in the future. Keep in mind that your parent DAO will have full authority to execute anything it wants to on behalf of this DAO.", + "becomeSubDaoActionDescription_created": "The parent DAO needs to accept this request to complete the ownership transfer and become your parent. Once the transfer is complete, only your new parent DAO can transfer ownership in the future. Keep in mind that your parent DAO will have full authority to execute anything it wants to on behalf of this DAO.", + "becomeSubDaoDescription": "Request to become a SubDAO of a DAO.", "betterNonPfmIbcPathAvailable": "A better path exists that unwinds the IBC token properly, but it requires hops that cannot be performed in a single proposal due to the configuration of one or more of the chains involved. You may safely use the direct path above, though it likely results in an undesirable IBC token on the final chain that will eventually need to be unwound. If you wish to unwind it manually, follow the path below by creating an individual proposal for the first hop, then a second proposal once the first one is passed and executed, and so on.", "betterPfmIbcPathAvailable_one": "A better path exists that unwinds the IBC token properly, but it requires you to have an account on {{chains}}. An account must exist on each intermediary chain in a multi-hop transaction to act as a failsafe in the event of catastrophic failure (unlikely). Either a cross-chain or ICA account works and will be automatically detected once created. You may safely use the direct path above, though it likely results in an undesirable IBC token on the final chain that will eventually need to be unwound.", "betterPfmIbcPathAvailable_other": "A better path exists that unwinds the IBC token properly, but it requires you to have accounts on the following chains: {{chains}}. An account must exist on each intermediary chain in a multi-hop transaction to act as a failsafe in the event of catastrophic failure (unlikely). Either a cross-chain or ICA account works and will be automatically detected once created. You may safely use the direct path above, though it likely results in an undesirable IBC token on the final chain that will eventually need to be unwound.", @@ -1564,6 +1575,7 @@ "title": { "404": "404: Not Found", "500": "500: Error", + "acceptSubDao": "Accept SubDAO Request", "accepted": "Accepted", "acceptingSubmissions": "Accepting submissions", "account": "Account", @@ -1590,6 +1602,7 @@ "averages": "Averages", "balance": "Balance", "balances": "Balances", + "becomeSubDao": "Become SubDAO", "beforeYouEnter": "Before you enter", "beginVesting": "Begin vesting", "blockCompleted": "Block completed", diff --git a/packages/stateful/actions/core/dao_governance/index.ts b/packages/stateful/actions/core/dao_governance/index.ts index a75740b40..ad16d2932 100644 --- a/packages/stateful/actions/core/dao_governance/index.ts +++ b/packages/stateful/actions/core/dao_governance/index.ts @@ -6,7 +6,6 @@ import { makeDaoAdminExecAction } from './DaoAdminExec' import { makeEnableMultipleChoiceAction } from './EnableMultipleChoice' import { makeManageStorageItemsAction } from './ManageStorageItems' import { makeManageSubDaoPauseAction } from './ManageSubDaoPause' -import { makeManageSubDaosAction } from './ManageSubDaos' import { makeManageVetoableDaosAction } from './ManageVetoableDaos' import { makeNeutronOverruleSubDaoProposalAction } from './NeutronOverruleSubDaoProposal' import { makeSetUpApproverAction } from './SetUpApprover' @@ -26,7 +25,6 @@ export const makeDaoGovernanceActionCategory: ActionCategoryMaker = ({ }), actionMakers: [ makeEnableMultipleChoiceAction, - makeManageSubDaosAction, makeManageStorageItemsAction, makeDaoAdminExecAction, makeUpgradeV1ToV2Action, diff --git a/packages/stateful/actions/core/index.ts b/packages/stateful/actions/core/index.ts index 62754a3ba..eff4bd6dc 100644 --- a/packages/stateful/actions/core/index.ts +++ b/packages/stateful/actions/core/index.ts @@ -15,6 +15,7 @@ import { makeDaoAppearanceActionCategory } from './dao_appearance' import { makeDaoGovernanceActionCategory } from './dao_governance' import { makeManageNftsActionCategory } from './nfts' import { makeSmartContractingActionCategory } from './smart_contracting' +import { makeSubDaosActionCategory } from './subdaos' import { makeTreasuryActionCategory } from './treasury' import { makeValenceActionCategory } from './valence' @@ -23,6 +24,7 @@ export const getCoreActionCategoryMakers = (): ActionCategoryMaker[] => [ makeCommonlyUsedCategory, makeTreasuryActionCategory, makeDaoGovernanceActionCategory, + makeSubDaosActionCategory, makeDaoAppearanceActionCategory, makeManageNftsActionCategory, makeSmartContractingActionCategory, diff --git a/packages/stateful/actions/core/smart_contracting/UpdateAdmin/index.tsx b/packages/stateful/actions/core/smart_contracting/UpdateAdmin/index.tsx index d396a9096..dd84bb62d 100644 --- a/packages/stateful/actions/core/smart_contracting/UpdateAdmin/index.tsx +++ b/packages/stateful/actions/core/smart_contracting/UpdateAdmin/index.tsx @@ -33,7 +33,7 @@ import { import { useActionOptions } from '../../../react' import { UpdateAdminComponent as StatelessUpdateAdminComponent } from './Component' -interface UpdateAdminData { +export type UpdateAdminData = { chainId: string contract: string newAdmin: string diff --git a/packages/stateful/actions/core/subdaos/AcceptSubDao/Component.stories.tsx b/packages/stateful/actions/core/subdaos/AcceptSubDao/Component.stories.tsx new file mode 100644 index 000000000..cc7d8e1dd --- /dev/null +++ b/packages/stateful/actions/core/subdaos/AcceptSubDao/Component.stories.tsx @@ -0,0 +1,27 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react' + +import { ReactHookFormDecorator } from '@dao-dao/storybook' + +import { AddressInput } from '../../../../components' +import { AcceptSubDaoComponent } from './Component' + +export default { + title: + 'DAO DAO / packages / stateful / actions / core / subdaos / AcceptSubDao', + component: AcceptSubDaoComponent, + decorators: [ReactHookFormDecorator], +} as ComponentMeta + +const Template: ComponentStory = (args) => ( + +) + +export const Default = Template.bind({}) +Default.args = { + fieldNamePrefix: '', + isCreating: true, + errors: {}, + options: { + AddressInput, + }, +} diff --git a/packages/stateful/actions/core/subdaos/AcceptSubDao/Component.tsx b/packages/stateful/actions/core/subdaos/AcceptSubDao/Component.tsx new file mode 100644 index 000000000..00847c900 --- /dev/null +++ b/packages/stateful/actions/core/subdaos/AcceptSubDao/Component.tsx @@ -0,0 +1,181 @@ +import { ComponentType, useEffect, useState } from 'react' +import { useFormContext } from 'react-hook-form' +import { useTranslation } from 'react-i18next' + +import { InputErrorMessage, InputLabel } from '@dao-dao/stateless' +import { AddressInputProps } from '@dao-dao/types' +import { ActionComponent, ActionKey } from '@dao-dao/types/actions' +import { + isValidBech32Address, + makeValidateAddress, + validateRequired, +} from '@dao-dao/utils' + +import { useActionOptions } from '../../../react' +import { DaoAdminExecData } from '../../dao_governance/DaoAdminExec/Component' +import { UpdateAdminData } from '../../smart_contracting/UpdateAdmin' +import { ManageSubDaosData } from '../ManageSubDaos/Component' + +export type AcceptSubDaoData = { + address: string +} + +type AcceptSubDaoDataOptions = { + AddressInput: ComponentType> +} + +export const AcceptSubDaoComponent: ActionComponent< + AcceptSubDaoDataOptions, + AcceptSubDaoData +> = ({ + fieldNamePrefix, + errors, + isCreating, + allActionsWithData, + index, + addAction, + options: { AddressInput }, +}) => { + const { t } = useTranslation() + const { + address: currentAddress, + chain: { chain_id: chainId, bech32_prefix: bech32Prefix }, + } = useActionOptions() + + const { watch, register, setValue, getValues } = + useFormContext() + + const addressFieldName = (fieldNamePrefix + 'address') as 'address' + + const address = watch(addressFieldName) + const isValid = !!address && isValidBech32Address(address, bech32Prefix) + const [otherActionsAdded, setOtherActionsAdded] = useState(false) + useEffect(() => { + if (!isCreating || !isValid) { + return + } + + const existingUpdateAdminIndex = allActionsWithData.findIndex( + (a, i) => + i > index && + a.actionKey === ActionKey.DaoAdminExec && + (a.data as DaoAdminExecData)?._actionData?.length === 1 && + (a.data as DaoAdminExecData)._actionData![0].actionKey === + ActionKey.UpdateAdmin && + (a.data as DaoAdminExecData)._actionData![0].data.newAdmin === + currentAddress + ) + const existingManageSubDaosIndex = allActionsWithData.findIndex( + (a, i) => i > index && a.actionKey === ActionKey.ManageSubDaos + ) + + if (existingUpdateAdminIndex === -1) { + addAction( + { + actionKey: ActionKey.DaoAdminExec, + data: { + coreAddress: address, + _actionData: [ + { + actionKey: ActionKey.UpdateAdmin, + data: { + chainId, + contract: address, + newAdmin: currentAddress, + } as UpdateAdminData, + }, + ], + } as DaoAdminExecData, + }, + // After current action. + index + 1 + ) + } else { + // Path to the address field on the update admin sub-action of the DAO + // admin exec action. + const existingAddressFieldName = fieldNamePrefix.replace( + new RegExp(`${index}\\.data.$`), + `${existingUpdateAdminIndex}.data._actionData.0.data.contract` + ) + + // If the address isn't correct, update the existing one. + if (getValues(existingAddressFieldName as any) !== address) { + setValue(existingAddressFieldName as any, address) + } + } + + if (existingManageSubDaosIndex === -1) { + addAction( + { + actionKey: ActionKey.ManageSubDaos, + data: { + toAdd: [ + { + addr: address, + }, + ], + toRemove: [], + } as ManageSubDaosData, + }, + // After DAO admin exec / update admin action. + index + 2 + ) + } else { + // Path to the address field on the manage subDAOs action. + const existingAddressFieldName = fieldNamePrefix.replace( + new RegExp(`${index}\\.data.$`), + `${existingManageSubDaosIndex}.data.toAdd.0.addr` + ) + + // If the address isn't correct, update the existing one. + if (getValues(existingAddressFieldName as any) !== address) { + setValue(existingAddressFieldName as any, address) + } + } + + setOtherActionsAdded(true) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + isCreating, + isValid, + address, + index, + addAction, + currentAddress, + chainId, + fieldNamePrefix, + getValues, + setValue, + ]) + + return ( + <> +
+ {isCreating && ( +

+ {t('info.acceptSubDaoActionDescription')} +

+ )} + +
+ + + +
+ + {otherActionsAdded && ( +

+ {t('info.acceptSubDaoActionOtherActionsAdded')} +

+ )} +
+ + ) +} diff --git a/packages/stateful/actions/core/subdaos/AcceptSubDao/README.md b/packages/stateful/actions/core/subdaos/AcceptSubDao/README.md new file mode 100644 index 000000000..3a0552d35 --- /dev/null +++ b/packages/stateful/actions/core/subdaos/AcceptSubDao/README.md @@ -0,0 +1,20 @@ +# AcceptSubDao + +Accept SubDAO join request and complete its ownership transfer. + +## Bulk import format + +This is relevant when bulk importing actions, as described in [this +guide](https://github.com/DA0-DA0/dao-dao-ui/wiki/Bulk-importing-actions). + +### Key + +`acceptSubDao` + +### Data format + +```json +{ + "address": "" +} +``` diff --git a/packages/stateful/actions/core/subdaos/AcceptSubDao/index.tsx b/packages/stateful/actions/core/subdaos/AcceptSubDao/index.tsx new file mode 100644 index 000000000..6a452abf8 --- /dev/null +++ b/packages/stateful/actions/core/subdaos/AcceptSubDao/index.tsx @@ -0,0 +1,71 @@ +import { CheckEmoji } from '@dao-dao/stateless' +import { + ActionComponent, + ActionKey, + ActionMaker, + UseDecodedCosmosMsg, + UseDefaults, +} from '@dao-dao/types/actions' +import { makeWasmMessage } from '@dao-dao/utils' + +import { AddressInput } from '../../../../components' +import { AcceptSubDaoComponent, AcceptSubDaoData } from './Component' + +const useDefaults: UseDefaults = () => ({ + address: '', +}) + +const useDecodedCosmosMsg: UseDecodedCosmosMsg = ( + msg: Record +) => { + try { + const match = Boolean(msg.wasm.execute.msg.accept_admin_nomination) + + if (match) { + return { + match, + data: { + address: msg.wasm.execute.contract_addr, + }, + } + } + + return { match: false } + } catch (e) { + return { match: false } + } +} + +const Component: ActionComponent = (props) => { + return +} + +export const makeAcceptSubDaoAction: ActionMaker = ({ + t, +}) => { + function useTransformToCosmos() { + return ({ address }: { address: string }) => + makeWasmMessage({ + wasm: { + execute: { + contract_addr: address, + funds: [], + msg: { + accept_admin_nomination: {}, + }, + }, + }, + }) + } + + return { + key: ActionKey.AcceptSubDao, + Icon: CheckEmoji, + label: t('title.acceptSubDao'), + description: t('info.acceptSubDaoDescription'), + Component, + useDefaults, + useTransformToCosmos, + useDecodedCosmosMsg, + } +} diff --git a/packages/stateful/actions/core/subdaos/BecomeSubDao/Component.stories.tsx b/packages/stateful/actions/core/subdaos/BecomeSubDao/Component.stories.tsx new file mode 100644 index 000000000..282b0cf7c --- /dev/null +++ b/packages/stateful/actions/core/subdaos/BecomeSubDao/Component.stories.tsx @@ -0,0 +1,27 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react' + +import { ReactHookFormDecorator } from '@dao-dao/storybook' + +import { AddressInput } from '../../../../components' +import { BecomeSubDaoComponent } from './Component' + +export default { + title: + 'DAO DAO / packages / stateful / actions / core / subdaos / BecomeSubDao', + component: BecomeSubDaoComponent, + decorators: [ReactHookFormDecorator], +} as ComponentMeta + +const Template: ComponentStory = (args) => ( + +) + +export const Default = Template.bind({}) +Default.args = { + fieldNamePrefix: '', + isCreating: true, + errors: {}, + options: { + AddressInput, + }, +} diff --git a/packages/stateful/actions/core/subdaos/BecomeSubDao/Component.tsx b/packages/stateful/actions/core/subdaos/BecomeSubDao/Component.tsx new file mode 100644 index 000000000..7178c132a --- /dev/null +++ b/packages/stateful/actions/core/subdaos/BecomeSubDao/Component.tsx @@ -0,0 +1,58 @@ +import { ComponentType } from 'react' +import { useFormContext } from 'react-hook-form' +import { useTranslation } from 'react-i18next' + +import { InputErrorMessage, InputLabel } from '@dao-dao/stateless' +import { AddressInputProps } from '@dao-dao/types' +import { ActionComponent } from '@dao-dao/types/actions' +import { makeValidateAddress, validateRequired } from '@dao-dao/utils' + +import { useActionOptions } from '../../../react' + +export type BecomeSubDaoData = { + admin: string +} + +type BecomeSubDaoDataOptions = { + AddressInput: ComponentType> +} + +export const BecomeSubDaoComponent: ActionComponent< + BecomeSubDaoDataOptions, + BecomeSubDaoData +> = ({ fieldNamePrefix, errors, isCreating, options: { AddressInput } }) => { + const { t } = useTranslation() + const { + chain: { bech32_prefix: bech32Prefix }, + } = useActionOptions() + + const { register } = useFormContext() + + const adminFieldName = (fieldNamePrefix + 'admin') as 'admin' + + return ( + <> +
+

+ {t('info.becomeSubDaoActionDescription', { + context: !isCreating ? 'created' : undefined, + })} +

+ +
+ + +
+ +
+ + ) +} diff --git a/packages/stateful/actions/core/subdaos/BecomeSubDao/README.md b/packages/stateful/actions/core/subdaos/BecomeSubDao/README.md new file mode 100644 index 000000000..aa802592b --- /dev/null +++ b/packages/stateful/actions/core/subdaos/BecomeSubDao/README.md @@ -0,0 +1,20 @@ +# BecomeSubDao + +To become a SubDAO, the first step would be to initiate ownership transfer by nominating your parent DAO, before that DAO can accept the ownership transfer. + +## Bulk import format + +This is relevant when bulk importing actions, as described in [this +guide](https://github.com/DA0-DA0/dao-dao-ui/wiki/Bulk-importing-actions). + +### Key + +`becomeSubDao` + +### Data format + +```json +{ + "admin": "" +} +``` diff --git a/packages/stateful/actions/core/subdaos/BecomeSubDao/index.tsx b/packages/stateful/actions/core/subdaos/BecomeSubDao/index.tsx new file mode 100644 index 000000000..238aa5166 --- /dev/null +++ b/packages/stateful/actions/core/subdaos/BecomeSubDao/index.tsx @@ -0,0 +1,75 @@ +import { BabyEmoji } from '@dao-dao/stateless' +import { + ActionComponent, + ActionContextType, + ActionKey, + ActionMaker, + UseDecodedCosmosMsg, + UseDefaults, +} from '@dao-dao/types/actions' +import { makeWasmMessage } from '@dao-dao/utils' + +import { AddressInput } from '../../../../components' +import { BecomeSubDaoComponent, BecomeSubDaoData } from './Component' + +const useDefaults: UseDefaults = () => ({ + admin: '', +}) + +const useDecodedCosmosMsg: UseDecodedCosmosMsg = ( + msg: Record +) => { + try { + return { + match: true, + data: { + admin: msg.wasm.execute.msg.nominate_admin.admin, + }, + } + } catch { + return { match: false } + } +} + +const Component: ActionComponent = (props) => { + return +} + +export const makeBecomeSubDaoAction: ActionMaker = ({ + t, + address, + context, +}) => { + function useTransformToCosmos() { + return ({ admin }: { admin: string }) => + makeWasmMessage({ + wasm: { + execute: { + contract_addr: address, + funds: [], + msg: { + nominate_admin: { + admin, + }, + }, + }, + }, + }) + } + + return { + key: ActionKey.BecomeSubDao, + Icon: BabyEmoji, + label: t('title.becomeSubDao'), + description: t('info.becomeSubDaoDescription'), + Component, + useDefaults, + useTransformToCosmos, + useDecodedCosmosMsg, + notReusable: true, + // If parent DAO exists, hide this action. + hideFromPicker: + context.type === ActionContextType.Dao && + context.dao.info.parentDao !== null, + } +} diff --git a/packages/stateful/actions/core/dao_governance/ManageSubDaos/Component.stories.tsx b/packages/stateful/actions/core/subdaos/ManageSubDaos/Component.stories.tsx similarity index 90% rename from packages/stateful/actions/core/dao_governance/ManageSubDaos/Component.stories.tsx rename to packages/stateful/actions/core/subdaos/ManageSubDaos/Component.stories.tsx index b26ec46a4..afe02b4af 100644 --- a/packages/stateful/actions/core/dao_governance/ManageSubDaos/Component.stories.tsx +++ b/packages/stateful/actions/core/subdaos/ManageSubDaos/Component.stories.tsx @@ -8,7 +8,7 @@ import { ManageSubDaosComponent } from './Component' export default { title: - 'DAO DAO / packages / stateful / actions / core / dao_governance / ManageSubDaos', + 'DAO DAO / packages / stateful / actions / core / subdaos / ManageSubDaos', component: ManageSubDaosComponent, decorators: [ReactHookFormDecorator], } as ComponentMeta diff --git a/packages/stateful/actions/core/dao_governance/ManageSubDaos/Component.tsx b/packages/stateful/actions/core/subdaos/ManageSubDaos/Component.tsx similarity index 99% rename from packages/stateful/actions/core/dao_governance/ManageSubDaos/Component.tsx rename to packages/stateful/actions/core/subdaos/ManageSubDaos/Component.tsx index 24fc7c071..b0d45253e 100644 --- a/packages/stateful/actions/core/dao_governance/ManageSubDaos/Component.tsx +++ b/packages/stateful/actions/core/subdaos/ManageSubDaos/Component.tsx @@ -20,7 +20,7 @@ import { makeValidateAddress, validateRequired } from '@dao-dao/utils' import { useActionOptions } from '../../../react' -export interface ManageSubDaosData { +export type ManageSubDaosData = { toAdd: SubDao[] toRemove: { address: string }[] } diff --git a/packages/stateful/actions/core/dao_governance/ManageSubDaos/README.md b/packages/stateful/actions/core/subdaos/ManageSubDaos/README.md similarity index 100% rename from packages/stateful/actions/core/dao_governance/ManageSubDaos/README.md rename to packages/stateful/actions/core/subdaos/ManageSubDaos/README.md diff --git a/packages/stateful/actions/core/dao_governance/ManageSubDaos/index.tsx b/packages/stateful/actions/core/subdaos/ManageSubDaos/index.tsx similarity index 100% rename from packages/stateful/actions/core/dao_governance/ManageSubDaos/index.tsx rename to packages/stateful/actions/core/subdaos/ManageSubDaos/index.tsx diff --git a/packages/stateful/actions/core/subdaos/index.ts b/packages/stateful/actions/core/subdaos/index.ts new file mode 100644 index 000000000..111d1af22 --- /dev/null +++ b/packages/stateful/actions/core/subdaos/index.ts @@ -0,0 +1,16 @@ +import { ActionCategoryKey, ActionCategoryMaker } from '@dao-dao/types' + +import { makeAcceptSubDaoAction } from './AcceptSubDao' +import { makeBecomeSubDaoAction } from './BecomeSubDao' +import { makeManageSubDaosAction } from './ManageSubDaos' + +export const makeSubDaosActionCategory: ActionCategoryMaker = ({ t }) => ({ + key: ActionCategoryKey.SubDaos, + label: t('actionCategory.subDaosLabel'), + description: t('actionCategory.subDaosDescription'), + actionMakers: [ + makeManageSubDaosAction, + makeBecomeSubDaoAction, + makeAcceptSubDaoAction, + ], +}) diff --git a/packages/stateless/components/emoji.tsx b/packages/stateless/components/emoji.tsx index 229082db6..8114cd067 100644 --- a/packages/stateless/components/emoji.tsx +++ b/packages/stateless/components/emoji.tsx @@ -276,3 +276,7 @@ export const PlayPauseEmoji = () => ( export const PufferfishEmoji = () => ( ) + +export const CheckEmoji = () => ( + +) diff --git a/packages/types/actions.ts b/packages/types/actions.ts index ed4d302f2..e98627896 100644 --- a/packages/types/actions.ts +++ b/packages/types/actions.ts @@ -21,6 +21,7 @@ export enum ActionCategoryKey { ChainGovernance = 'chainGovernance', DaoAppearance = 'daoAppearance', DaoGovernance = 'daoGovernance', + SubDaos = 'subDaos', SmartContracting = 'smartContracting', Treasury = 'treasury', Rebalancer = 'rebalancer', @@ -102,6 +103,9 @@ export enum ActionKey { CreatePost = 'createPost', UpdatePost = 'updatePost', DeletePost = 'deletePost', + // Become SubDAO + AcceptSubDao = 'acceptSubDao', + BecomeSubDao = 'becomeSubDao', } export type ActionAndData = {