From 0ccb2e42511abb1385dafee2dce355a249795400 Mon Sep 17 00:00:00 2001 From: Noah Saso Date: Thu, 8 Feb 2024 19:13:11 -0800 Subject: [PATCH 1/5] Added action to migrate token factory issuer for Migaloo DAOs. --- packages/i18n/locales/en/translation.json | 4 + packages/state/recoil/selectors/contract.ts | 27 ++-- .../stateful/creators/TokenBased/mutate.ts | 2 +- .../Component.stories.tsx | 30 +++++ .../Component.tsx | 16 +++ .../README.md | 20 +++ .../index.tsx | 127 ++++++++++++++++++ .../DaoVotingTokenStaked/actions/index.ts | 1 + .../adapters/DaoVotingTokenStaked/index.ts | 2 + packages/stateless/components/emoji.tsx | 4 + packages/types/actions.ts | 1 + packages/types/chain.ts | 5 +- packages/utils/constants/chains.ts | 20 +-- packages/utils/constants/contracts.ts | 3 +- 14 files changed, 239 insertions(+), 23 deletions(-) create mode 100644 packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.stories.tsx create mode 100644 packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.tsx create mode 100644 packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/README.md create mode 100644 packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/index.tsx diff --git a/packages/i18n/locales/en/translation.json b/packages/i18n/locales/en/translation.json index 6a1d4e4f5e..fe6bb18901 100644 --- a/packages/i18n/locales/en/translation.json +++ b/packages/i18n/locales/en/translation.json @@ -336,6 +336,7 @@ "pick": "Mining pick", "playPause": "Play pause", "printer": "Printer", + "pufferfish": "Pufferfish", "raisedHand": "Raised hand", "recycle": "Recycle", "robot": "Robot", @@ -1059,6 +1060,8 @@ "mergeProfilesTooltip": "Your wallet is attached to multiple profiles. Merge them to avoid confusion.", "migrateFollowingDescription": "Followed DAOs require a migration to a new storage mechanism.", "migrateSmartContractActionDescription": "Migrate a CosmWasm contract to a new code ID.", + "migrateToOsmosisTokenFactoryIssuerExplanation": "The token factory module on Migaloo has been migrated to a new version that is more actively maintained. Because this DAO created a new token before the migration, the DAO's token factory contract that interacts with the chain module must now be upgraded. This action upgrades the token factory contract to a version that supports the new token factory module.", + "migrateTokenFactoryModuleDescription": "Update the DAO to support the new token factory module.", "minimumOutputRequiredDescription_dao": "Before the proposal is passed and executed, the swap price will fluctuate. If the price drops and no longer satisfies this minimum output required, the swap will not occur.", "minimumOutputRequiredDescription_gov": "Before the proposal is passed and executed, the swap price will fluctuate. If the price drops and no longer satisfies this minimum output required, the swap will not occur.", "minimumOutputRequiredDescription_wallet": "The exact swap price will fluctuate during the transaction, but the minimum output amount is guaranteed. If the price drops and no longer satisfies this minimum output required, the swap will not occur.", @@ -1644,6 +1647,7 @@ "mergeProfiles": "Merge Profiles", "migrateFollowing": "Migrate Followed DAOs", "migrateSmartContract": "Migrate Smart Contract", + "migrateTokenFactoryModule": "Migrate Token Factory Module", "minimumOutputRequired": "Minimum output required", "mint": "Mint", "mintNft": "Mint NFT", diff --git a/packages/state/recoil/selectors/contract.ts b/packages/state/recoil/selectors/contract.ts index d22177079b..f08194e25b 100644 --- a/packages/state/recoil/selectors/contract.ts +++ b/packages/state/recoil/selectors/contract.ts @@ -1,4 +1,4 @@ -import { CodeDetails } from '@cosmjs/cosmwasm-stargate' +import { CodeDetails, Contract } from '@cosmjs/cosmwasm-stargate' import { fromUtf8, toUtf8 } from '@cosmjs/encoding' import { selectorFamily } from 'recoil' @@ -58,25 +58,30 @@ export const contractInstantiateTimeSelector = selectorFamily< }, }) -export const contractAdminSelector = selectorFamily< - string | undefined, +export const contractDetailsSelector = selectorFamily< + Contract, WithChainId<{ contractAddress: string }> >({ - key: 'contractAdmin', + key: 'contractDetails', get: ({ contractAddress, chainId }) => async ({ get }) => { const client = get(cosmWasmClientForChainSelector(chainId)) - - try { - const contract = await client.getContract(contractAddress) - return contract.admin - } catch (_) { - return undefined - } + return await client.getContract(contractAddress) }, }) +export const contractAdminSelector = selectorFamily< + string | undefined, + WithChainId<{ contractAddress: string }> +>({ + key: 'contractAdmin', + get: + (params) => + ({ get }) => + get(contractDetailsSelector(params))?.admin, +}) + export const codeDetailsSelector = selectorFamily< CodeDetails, WithChainId<{ codeId: number }> diff --git a/packages/stateful/creators/TokenBased/mutate.ts b/packages/stateful/creators/TokenBased/mutate.ts index bf92488188..82f0e31f4b 100644 --- a/packages/stateful/creators/TokenBased/mutate.ts +++ b/packages/stateful/creators/TokenBased/mutate.ts @@ -82,7 +82,7 @@ export const mutate: DaoCreatorMutate = ( active_threshold, token_info: { new: { - token_issuer_code_id: codeIds.CwTokenfactoryIssuer, + token_issuer_code_id: codeIds.CwTokenfactoryIssuerOsmosis, subdenom: symbol.toLowerCase(), initial_balances: microInitialBalances, initial_dao_balance: microInitialTreasuryBalance, diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.stories.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.stories.tsx new file mode 100644 index 0000000000..b5f062b7b4 --- /dev/null +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.stories.tsx @@ -0,0 +1,30 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react' + +import { makeReactHookFormDecorator } from '@dao-dao/storybook' + +import { + MigrateToOsmosisTokenFactoryIssuerComponent, + MigrateToOsmosisTokenFactoryIssuerData, +} from './Component' + +export default { + title: + 'DAO DAO / packages / stateful / voting-module-adapter / adapters / DaoVotingTokenStaked / actions / MigrateToOsmosisTokenFactoryIssuer', + component: MigrateToOsmosisTokenFactoryIssuerComponent, + decorators: [ + makeReactHookFormDecorator(), + ], +} as ComponentMeta + +const Template: ComponentStory< + typeof MigrateToOsmosisTokenFactoryIssuerComponent +> = (args) => + +export const Default = Template.bind({}) +Default.args = { + fieldNamePrefix: '', + allActionsWithData: [], + index: 0, + data: {}, + isCreating: true, +} diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.tsx new file mode 100644 index 0000000000..94a419079e --- /dev/null +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.tsx @@ -0,0 +1,16 @@ +import { useTranslation } from 'react-i18next' + +import { ActionComponent } from '@dao-dao/types' + +export type MigrateToOsmosisTokenFactoryIssuerData = {} + +export const MigrateToOsmosisTokenFactoryIssuerComponent: ActionComponent = + () => { + const { t } = useTranslation() + + return ( +

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

+ ) + } diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/README.md b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/README.md new file mode 100644 index 0000000000..85239faf7a --- /dev/null +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/README.md @@ -0,0 +1,20 @@ +# MigrateToOsmosisTokenFactoryIssuer + +Migrate `cw-tokenfactory-issuer` from the CosmWasm x/tokenfactory implementation +to Osmosis's x/tokenfactory. Migaloo is migrating tokenfactory modules, so this +is needed to help DAO's update to the latest contract. + +## 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 + +`migrateToOsmosisTokenFactoryIssuer` + +### Data format + +```json +{} +``` diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/index.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/index.tsx new file mode 100644 index 0000000000..cf46ef9f1a --- /dev/null +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/index.tsx @@ -0,0 +1,127 @@ +import { useCallback } from 'react' + +import { + DaoVotingTokenStakedSelectors, + contractDetailsSelector, +} from '@dao-dao/state/recoil' +import { PufferfishEmoji, useCachedLoadable } from '@dao-dao/stateless' +import { ChainId } from '@dao-dao/types' +import { + ActionChainContextType, + ActionKey, + ActionMaker, + UseDecodedCosmosMsg, + UseDefaults, + UseHideFromPicker, + UseTransformToCosmos, +} from '@dao-dao/types/actions' +import { makeWasmMessage, objectMatchesStructure } from '@dao-dao/utils' + +import { useVotingModuleAdapterOptions } from '../../../../react/context' +import { useGovernanceTokenInfo } from '../../hooks' +import { + MigrateToOsmosisTokenFactoryIssuerComponent, + MigrateToOsmosisTokenFactoryIssuerData, +} from './Component' + +const useDefaults: UseDefaults< + MigrateToOsmosisTokenFactoryIssuerData +> = () => ({}) + +export const makeMigrateToOsmosisTokenFactoryIssuerAction: ActionMaker< + MigrateToOsmosisTokenFactoryIssuerData +> = ({ t, chainContext }) => { + // Only Migaloo DAOs need to migrate. + if ( + chainContext.chainId !== ChainId.MigalooMainnet || + chainContext.type !== ActionChainContextType.Supported + ) { + return null + } + + const useTransformToCosmos: UseTransformToCosmos< + MigrateToOsmosisTokenFactoryIssuerData + > = () => { + const { tokenFactoryIssuerAddress } = useGovernanceTokenInfo() + + return useCallback( + () => + makeWasmMessage({ + wasm: { + migrate: { + contract_addr: tokenFactoryIssuerAddress, + new_code_id: + chainContext.config.codeIds.CwTokenfactoryIssuerOsmosis, + msg: {}, + }, + }, + }), + [tokenFactoryIssuerAddress] + ) + } + + const useDecodedCosmosMsg: UseDecodedCosmosMsg< + MigrateToOsmosisTokenFactoryIssuerData + > = (msg: Record) => { + const { tokenFactoryIssuerAddress } = useGovernanceTokenInfo() + + return objectMatchesStructure(msg, { + wasm: { + migrate: { + contract_addr: {}, + new_code_id: {}, + msg: {}, + }, + }, + }) && msg.wasm.migrate.contract_addr === tokenFactoryIssuerAddress + ? { + match: true, + data: {}, + } + : { + match: false, + } + } + + // Only show in picker if using cw-tokenfactory-issuer contract and it's on the + // old version of the contract. + const useHideFromPicker: UseHideFromPicker = () => { + const { chainId, votingModuleAddress } = useVotingModuleAdapterOptions() + + const tfIssuer = useCachedLoadable( + DaoVotingTokenStakedSelectors.validatedTokenfactoryIssuerContractSelector( + { + contractAddress: votingModuleAddress, + chainId, + } + ) + ) + const tfIssuerContract = useCachedLoadable( + tfIssuer.state === 'hasValue' && tfIssuer.contents + ? contractDetailsSelector({ + contractAddress: tfIssuer.contents, + chainId, + }) + : undefined + ) + + return ( + !chainContext.config.codeIds.CwTokenfactoryIssuerCosmWasm || + tfIssuerContract.state !== 'hasValue' || + tfIssuerContract.contents.codeId !== + chainContext.config.codeIds.CwTokenfactoryIssuerCosmWasm + ) + } + + return { + key: ActionKey.MigrateToOsmosisTokenFactoryIssuer, + Icon: PufferfishEmoji, + label: t('title.migrateTokenFactoryModule'), + description: t('info.migrateTokenFactoryModuleDescription'), + Component: MigrateToOsmosisTokenFactoryIssuerComponent, + useDefaults, + useTransformToCosmos, + useDecodedCosmosMsg, + useHideFromPicker, + } +} diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/index.ts b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/index.ts index 8775b26d2d..0c25389183 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/index.ts +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/index.ts @@ -1,3 +1,4 @@ +export * from './MigrateToOsmosisTokenFactoryIssuer' export * from './Mint' export * from './UpdateMinterAllowance' export * from './UpdateStakingConfig' diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts index 29d22aa277..277c779223 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts @@ -12,6 +12,7 @@ import { } from '@dao-dao/utils' import { + makeMigrateToOsmosisTokenFactoryIssuerAction, makeMintAction, makeUpdateMinterAllowanceAction, makeUpdateStakingConfigAction, @@ -58,6 +59,7 @@ export const DaoVotingTokenStakedAdapter: VotingModuleAdapter = { makeMintAction, makeUpdateMinterAllowanceAction, makeUpdateStakingConfigAction, + makeMigrateToOsmosisTokenFactoryIssuerAction, ], }), ], diff --git a/packages/stateless/components/emoji.tsx b/packages/stateless/components/emoji.tsx index 345820d70d..229082db65 100644 --- a/packages/stateless/components/emoji.tsx +++ b/packages/stateless/components/emoji.tsx @@ -272,3 +272,7 @@ export const ComputerDiskEmoji = () => ( export const PlayPauseEmoji = () => ( ) + +export const PufferfishEmoji = () => ( + +) diff --git a/packages/types/actions.ts b/packages/types/actions.ts index 9b57b3bb01..7ad0f858ad 100644 --- a/packages/types/actions.ts +++ b/packages/types/actions.ts @@ -81,6 +81,7 @@ export enum ActionKey { ManageSubDaoPause = 'manageSubDaoPause', UpdatePreProposeConfig = 'updatePreProposeConfig', UpdateProposalConfig = 'updateProposalConfig', + MigrateToOsmosisTokenFactoryIssuer = 'migrateToOsmosisTokenFactoryIssuer', // Press CreatePost = 'createPost', UpdatePost = 'updatePost', diff --git a/packages/types/chain.ts b/packages/types/chain.ts index 5987217859..94eb32d8ef 100644 --- a/packages/types/chain.ts +++ b/packages/types/chain.ts @@ -175,7 +175,7 @@ export type CodeIdConfig = { // https://github.com/DA0-DA0/dao-contracts CwPayrollFactory: number CwTokenSwap: number - CwTokenfactoryIssuer: number + CwTokenfactoryIssuerOsmosis: number CwVesting: number DaoCore: number DaoMigrator: number @@ -189,6 +189,9 @@ export type CodeIdConfig = { DaoVotingCw721Staked: number DaoVotingTokenStaked: number + // For migrating Migaloo DAOs from cosmwasm to osmosis x/tokenfactory. + CwTokenfactoryIssuerCosmWasm?: number + // For migrating v1 to v2 DAOs, and some chains use CW20s. Cw20Base?: number Cw20Stake?: number diff --git a/packages/utils/constants/chains.ts b/packages/utils/constants/chains.ts index f90b4eb7bd..b45557e6e2 100644 --- a/packages/utils/constants/chains.ts +++ b/packages/utils/constants/chains.ts @@ -72,7 +72,7 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 4042, CwTokenSwap: 4043, - CwTokenfactoryIssuer: 4045, + CwTokenfactoryIssuerOsmosis: 4045, CwVesting: 4046, DaoCore: 4047, DaoMigrator: 4048, @@ -249,7 +249,7 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 353, CwTokenSwap: 354, - CwTokenfactoryIssuer: 364, + CwTokenfactoryIssuerOsmosis: 364, CwVesting: 355, DaoCore: 365, DaoMigrator: -1, // not needed since only v2 DAOs exist @@ -441,7 +441,7 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 553, CwTokenSwap: 564, - CwTokenfactoryIssuer: 565, + CwTokenfactoryIssuerOsmosis: 565, CwVesting: 703, DaoCore: 567, DaoMigrator: -1, // not needed since only v2 DAOs exist @@ -572,7 +572,7 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 148, CwTokenSwap: 149, - CwTokenfactoryIssuer: 150, + CwTokenfactoryIssuerOsmosis: 150, CwVesting: 151, DaoCore: 153, DaoMigrator: -1, // not needed since only v2 DAOs exist @@ -742,7 +742,8 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 286, CwTokenSwap: 287, - CwTokenfactoryIssuer: 288, + CwTokenfactoryIssuerOsmosis: 401, + CwTokenfactoryIssuerCosmWasm: 288, CwVesting: 290, DaoCore: 291, DaoMigrator: -1, @@ -1110,7 +1111,7 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 4062, CwTokenSwap: 4063, - CwTokenfactoryIssuer: 4065, + CwTokenfactoryIssuerOsmosis: 4065, CwVesting: 4066, DaoCore: 4067, DaoMigrator: 4068, @@ -1158,7 +1159,7 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 5841, CwTokenSwap: 5842, - CwTokenfactoryIssuer: 5843, + CwTokenfactoryIssuerOsmosis: 5843, CwVesting: 5844, DaoCore: 5845, DaoMigrator: -1, // not needed since only v2 DAOs exist @@ -1200,7 +1201,7 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 3461, CwTokenSwap: 3462, - CwTokenfactoryIssuer: 3463, + CwTokenfactoryIssuerOsmosis: 3463, CwVesting: 3464, DaoCore: 3465, DaoMigrator: -1, // not needed since only v2 DAOs exist @@ -1244,7 +1245,8 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 3, CwTokenSwap: 4, - CwTokenfactoryIssuer: 5, + CwTokenfactoryIssuerOsmosis: 65, + CwTokenfactoryIssuerCosmWasm: 5, CwVesting: 6, DaoCore: 7, DaoMigrator: -1, diff --git a/packages/utils/constants/contracts.ts b/packages/utils/constants/contracts.ts index 5b44efc31a..aadd5e4e74 100644 --- a/packages/utils/constants/contracts.ts +++ b/packages/utils/constants/contracts.ts @@ -4,7 +4,8 @@ export enum ContractName { Cw3FixedMultisig = 'crates.io:cw3-fixed-multisig', Cw3FlexMultisig = 'crates.io:cw3-flex-multisig', CwTokenSwap = 'crates.io:cw-token-swap', - CwTokenfactoryIssuer = 'crates.io:cw-tokenfactory-issuer', + // This contract left out the `crates.io:` prefix. + CwTokenfactoryIssuer = 'cw-tokenfactory-issuer', PolytoneProxy = 'crates.io:polytone-proxy', PreProposeSingle = 'crates.io:dao-pre-propose-single', PreProposeApprovalSingle = 'crates.io:dao-pre-propose-approval-single', From 59c25e6e0412a5c755b89b499332e67188591329 Mon Sep 17 00:00:00 2001 From: Noah Saso Date: Thu, 8 Feb 2024 19:50:37 -0800 Subject: [PATCH 2/5] Prevent mint action on old versions of tokenfactory issuer on Migaloo. --- .../actions/Mint/index.tsx | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/Mint/index.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/Mint/index.tsx index 47da816dcb..c013cc1609 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/Mint/index.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/Mint/index.tsx @@ -1,8 +1,13 @@ import { useCallback } from 'react' -import { DaoVotingTokenStakedSelectors } from '@dao-dao/state/recoil' +import { + DaoVotingTokenStakedSelectors, + contractDetailsSelector, +} from '@dao-dao/state/recoil' import { HerbEmoji, useCachedLoadable } from '@dao-dao/stateless' +import { ChainId } from '@dao-dao/types' import { + ActionChainContextType, ActionComponent, ActionKey, ActionMaker, @@ -18,6 +23,7 @@ import { objectMatchesStructure, } from '@dao-dao/utils' +import { useActionOptions } from '../../../../../actions' import { AddressInput } from '../../../../../components/AddressInput' import { useVotingModuleAdapterOptions } from '../../../../react/context' import { useGovernanceTokenInfo } from '../../hooks' @@ -108,6 +114,7 @@ const Component: ActionComponent = (props) => { // Only show in picker if using cw-tokenfactory-issuer contract. const useHideFromPicker: UseHideFromPicker = () => { const { chainId, votingModuleAddress } = useVotingModuleAdapterOptions() + const { chainContext } = useActionOptions() const tfIssuer = useCachedLoadable( DaoVotingTokenStakedSelectors.validatedTokenfactoryIssuerContractSelector({ @@ -115,8 +122,25 @@ const useHideFromPicker: UseHideFromPicker = () => { chainId, }) ) + const tfIssuerContract = useCachedLoadable( + tfIssuer.state === 'hasValue' && tfIssuer.contents + ? contractDetailsSelector({ + contractAddress: tfIssuer.contents, + chainId, + }) + : undefined + ) - return tfIssuer.state !== 'hasValue' || !tfIssuer.contents + return ( + tfIssuer.state !== 'hasValue' || + !tfIssuer.contents || + // Disallow minting on Miagloo if cw-tokenfactory-issuer is on old version. + (chainContext.chainId === ChainId.MigalooMainnet && + chainContext.type === ActionChainContextType.Supported && + (tfIssuerContract.state !== 'hasValue' || + tfIssuerContract.contents.codeId === + chainContext.config.codeIds.CwTokenfactoryIssuerCosmWasm)) + ) } export const makeMintAction: ActionMaker = ({ t, address }) => { From 292c2faa044d35880f3bef81ba898a0aed7a65f4 Mon Sep 17 00:00:00 2001 From: Noah Saso Date: Fri, 9 Feb 2024 11:22:59 -0800 Subject: [PATCH 3/5] Order actions manually. --- packages/i18n/locales/en/translation.json | 2 +- .../Component.stories.tsx | 28 +++++ .../Component.tsx | 15 +++ .../README.md | 4 +- .../index.tsx | 22 ++-- .../Component.stories.tsx | 30 ----- .../Component.tsx | 16 --- .../DaoVotingTokenStaked/actions/index.ts | 2 +- .../adapters/DaoVotingTokenStaked/index.ts | 4 +- .../components/actions/ActionLibrary.tsx | 113 ++++++++++-------- packages/types/actions.ts | 8 +- 11 files changed, 129 insertions(+), 115 deletions(-) create mode 100644 packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/Component.stories.tsx create mode 100644 packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/Component.tsx rename packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/{MigrateToOsmosisTokenFactoryIssuer => MigrateMigalooV4TokenFactory}/README.md (85%) rename packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/{MigrateToOsmosisTokenFactoryIssuer => MigrateMigalooV4TokenFactory}/index.tsx (86%) delete mode 100644 packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.stories.tsx delete mode 100644 packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.tsx diff --git a/packages/i18n/locales/en/translation.json b/packages/i18n/locales/en/translation.json index fe6bb18901..628ad965af 100644 --- a/packages/i18n/locales/en/translation.json +++ b/packages/i18n/locales/en/translation.json @@ -1059,8 +1059,8 @@ "mergeProfilesExplanation": "Select the profile you want to keep (the rest will be merged into it).", "mergeProfilesTooltip": "Your wallet is attached to multiple profiles. Merge them to avoid confusion.", "migrateFollowingDescription": "Followed DAOs require a migration to a new storage mechanism.", + "migrateMigalooV4TokenFactoryExplanation": "The token factory module on Migaloo has been migrated to a new version that is more actively maintained. Because this DAO created a new token before the migration, the DAO's token factory contract that interacts with the chain module must now be upgraded. This action upgrades the token factory contract to a version that supports the new token factory module.", "migrateSmartContractActionDescription": "Migrate a CosmWasm contract to a new code ID.", - "migrateToOsmosisTokenFactoryIssuerExplanation": "The token factory module on Migaloo has been migrated to a new version that is more actively maintained. Because this DAO created a new token before the migration, the DAO's token factory contract that interacts with the chain module must now be upgraded. This action upgrades the token factory contract to a version that supports the new token factory module.", "migrateTokenFactoryModuleDescription": "Update the DAO to support the new token factory module.", "minimumOutputRequiredDescription_dao": "Before the proposal is passed and executed, the swap price will fluctuate. If the price drops and no longer satisfies this minimum output required, the swap will not occur.", "minimumOutputRequiredDescription_gov": "Before the proposal is passed and executed, the swap price will fluctuate. If the price drops and no longer satisfies this minimum output required, the swap will not occur.", diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/Component.stories.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/Component.stories.tsx new file mode 100644 index 0000000000..dad35aed0c --- /dev/null +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/Component.stories.tsx @@ -0,0 +1,28 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react' + +import { makeReactHookFormDecorator } from '@dao-dao/storybook' + +import { + MigrateMigalooV4TokenFactoryComponent, + MigrateMigalooV4TokenFactoryData, +} from './Component' + +export default { + title: + 'DAO DAO / packages / stateful / voting-module-adapter / adapters / DaoVotingTokenStaked / actions / MigrateMigalooV4TokenFactory', + component: MigrateMigalooV4TokenFactoryComponent, + decorators: [makeReactHookFormDecorator()], +} as ComponentMeta + +const Template: ComponentStory = ( + args +) => + +export const Default = Template.bind({}) +Default.args = { + fieldNamePrefix: '', + allActionsWithData: [], + index: 0, + data: {}, + isCreating: true, +} diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/Component.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/Component.tsx new file mode 100644 index 0000000000..498018679c --- /dev/null +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/Component.tsx @@ -0,0 +1,15 @@ +import { useTranslation } from 'react-i18next' + +import { ActionComponent } from '@dao-dao/types' + +export type MigrateMigalooV4TokenFactoryData = {} + +export const MigrateMigalooV4TokenFactoryComponent: ActionComponent = () => { + const { t } = useTranslation() + + return ( +

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

+ ) +} diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/README.md b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/README.md similarity index 85% rename from packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/README.md rename to packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/README.md index 85239faf7a..5d1b054724 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/README.md +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/README.md @@ -1,4 +1,4 @@ -# MigrateToOsmosisTokenFactoryIssuer +# MigrateMigalooV4TokenFactory Migrate `cw-tokenfactory-issuer` from the CosmWasm x/tokenfactory implementation to Osmosis's x/tokenfactory. Migaloo is migrating tokenfactory modules, so this @@ -11,7 +11,7 @@ guide](https://github.com/DA0-DA0/dao-dao-ui/wiki/Bulk-importing-actions). ### Key -`migrateToOsmosisTokenFactoryIssuer` +`migrateMigalooV4TokenFactory` ### Data format diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/index.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/index.tsx similarity index 86% rename from packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/index.tsx rename to packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/index.tsx index cf46ef9f1a..38a79c0993 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/index.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateMigalooV4TokenFactory/index.tsx @@ -20,16 +20,14 @@ import { makeWasmMessage, objectMatchesStructure } from '@dao-dao/utils' import { useVotingModuleAdapterOptions } from '../../../../react/context' import { useGovernanceTokenInfo } from '../../hooks' import { - MigrateToOsmosisTokenFactoryIssuerComponent, - MigrateToOsmosisTokenFactoryIssuerData, + MigrateMigalooV4TokenFactoryComponent, + MigrateMigalooV4TokenFactoryData, } from './Component' -const useDefaults: UseDefaults< - MigrateToOsmosisTokenFactoryIssuerData -> = () => ({}) +const useDefaults: UseDefaults = () => ({}) -export const makeMigrateToOsmosisTokenFactoryIssuerAction: ActionMaker< - MigrateToOsmosisTokenFactoryIssuerData +export const makeMigrateMigalooV4TokenFactoryAction: ActionMaker< + MigrateMigalooV4TokenFactoryData > = ({ t, chainContext }) => { // Only Migaloo DAOs need to migrate. if ( @@ -40,7 +38,7 @@ export const makeMigrateToOsmosisTokenFactoryIssuerAction: ActionMaker< } const useTransformToCosmos: UseTransformToCosmos< - MigrateToOsmosisTokenFactoryIssuerData + MigrateMigalooV4TokenFactoryData > = () => { const { tokenFactoryIssuerAddress } = useGovernanceTokenInfo() @@ -61,7 +59,7 @@ export const makeMigrateToOsmosisTokenFactoryIssuerAction: ActionMaker< } const useDecodedCosmosMsg: UseDecodedCosmosMsg< - MigrateToOsmosisTokenFactoryIssuerData + MigrateMigalooV4TokenFactoryData > = (msg: Record) => { const { tokenFactoryIssuerAddress } = useGovernanceTokenInfo() @@ -114,14 +112,16 @@ export const makeMigrateToOsmosisTokenFactoryIssuerAction: ActionMaker< } return { - key: ActionKey.MigrateToOsmosisTokenFactoryIssuer, + key: ActionKey.MigrateMigalooV4TokenFactory, Icon: PufferfishEmoji, label: t('title.migrateTokenFactoryModule'), description: t('info.migrateTokenFactoryModuleDescription'), - Component: MigrateToOsmosisTokenFactoryIssuerComponent, + Component: MigrateMigalooV4TokenFactoryComponent, useDefaults, useTransformToCosmos, useDecodedCosmosMsg, useHideFromPicker, + // Show at the top. + order: 1000, } } diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.stories.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.stories.tsx deleted file mode 100644 index b5f062b7b4..0000000000 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.stories.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { ComponentMeta, ComponentStory } from '@storybook/react' - -import { makeReactHookFormDecorator } from '@dao-dao/storybook' - -import { - MigrateToOsmosisTokenFactoryIssuerComponent, - MigrateToOsmosisTokenFactoryIssuerData, -} from './Component' - -export default { - title: - 'DAO DAO / packages / stateful / voting-module-adapter / adapters / DaoVotingTokenStaked / actions / MigrateToOsmosisTokenFactoryIssuer', - component: MigrateToOsmosisTokenFactoryIssuerComponent, - decorators: [ - makeReactHookFormDecorator(), - ], -} as ComponentMeta - -const Template: ComponentStory< - typeof MigrateToOsmosisTokenFactoryIssuerComponent -> = (args) => - -export const Default = Template.bind({}) -Default.args = { - fieldNamePrefix: '', - allActionsWithData: [], - index: 0, - data: {}, - isCreating: true, -} diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.tsx deleted file mode 100644 index 94a419079e..0000000000 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/MigrateToOsmosisTokenFactoryIssuer/Component.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { useTranslation } from 'react-i18next' - -import { ActionComponent } from '@dao-dao/types' - -export type MigrateToOsmosisTokenFactoryIssuerData = {} - -export const MigrateToOsmosisTokenFactoryIssuerComponent: ActionComponent = - () => { - const { t } = useTranslation() - - return ( -

- {t('info.migrateToOsmosisTokenFactoryIssuerExplanation')} -

- ) - } diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/index.ts b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/index.ts index 0c25389183..d3f20b7490 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/index.ts +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/actions/index.ts @@ -1,4 +1,4 @@ -export * from './MigrateToOsmosisTokenFactoryIssuer' +export * from './MigrateMigalooV4TokenFactory' export * from './Mint' export * from './UpdateMinterAllowance' export * from './UpdateStakingConfig' diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts index 277c779223..216db0fb5f 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts @@ -12,7 +12,7 @@ import { } from '@dao-dao/utils' import { - makeMigrateToOsmosisTokenFactoryIssuerAction, + makeMigrateMigalooV4TokenFactoryAction, makeMintAction, makeUpdateMinterAllowanceAction, makeUpdateStakingConfigAction, @@ -59,7 +59,7 @@ export const DaoVotingTokenStakedAdapter: VotingModuleAdapter = { makeMintAction, makeUpdateMinterAllowanceAction, makeUpdateStakingConfigAction, - makeMigrateToOsmosisTokenFactoryIssuerAction, + makeMigrateMigalooV4TokenFactoryAction, ], }), ], diff --git a/packages/stateless/components/actions/ActionLibrary.tsx b/packages/stateless/components/actions/ActionLibrary.tsx index 00ea0be1b0..dffcd0b7e9 100644 --- a/packages/stateless/components/actions/ActionLibrary.tsx +++ b/packages/stateless/components/actions/ActionLibrary.tsx @@ -130,9 +130,30 @@ export const ActionLibrary = ({ ? categories.find((c) => c.key === categoryKeySelected) : undefined - const showingActions = categoryKeySelected - ? (selectedCategory || categories[0]).actions - : filteredActions.slice(0, 10).map(({ item }) => item) + const showingActions = ( + categoryKeySelected + ? (selectedCategory || categories[0]).actions + : filteredActions.slice(0, 10).map(({ item }) => item) + ) + .filter( + (action) => + // Never show programmatic actions. + !action.programmaticOnly && + // Show if reusable or not already used. + (!action.notReusable || + !actionData.some((a) => a.actionKey === action.key)) + ) + .sort((a, b) => + a.order !== undefined && b.order !== undefined + ? a.order - b.order + : // Prioritize the action with an order set. + a.order + ? -1 + : b.order + ? 1 + : // Leave them sorted by the original order in the category definition. + 0 + ) // Ensure selected item is scrolled into view. useEffect(() => { @@ -284,54 +305,44 @@ export const ActionLibrary = ({ className="flex min-w-0 grow flex-col gap-2 pt-1 md:pb-1" ref={itemsListRef} > - {showingActions - .filter( - (action) => - // Never show programmatic actions. - !action.programmaticOnly && - // Show if reusable or not already used. - (!action.notReusable || - !actionData.some((a) => a.actionKey === action.key)) - ) - .map((action, index) => ( - - ))} + {showingActions.map((action, index) => ( + + ))} diff --git a/packages/types/actions.ts b/packages/types/actions.ts index 7ad0f858ad..095ed82374 100644 --- a/packages/types/actions.ts +++ b/packages/types/actions.ts @@ -81,7 +81,7 @@ export enum ActionKey { ManageSubDaoPause = 'manageSubDaoPause', UpdatePreProposeConfig = 'updatePreProposeConfig', UpdateProposalConfig = 'updateProposalConfig', - MigrateToOsmosisTokenFactoryIssuer = 'migrateToOsmosisTokenFactoryIssuer', + MigrateMigalooV4TokenFactory = 'migrateMigalooV4TokenFactory', // Press CreatePost = 'createPost', UpdatePost = 'updatePost', @@ -192,6 +192,12 @@ export interface Action { // and `notReusable`, while also preventing the user from going back to the // category action picker or removing the action. programmaticOnly?: boolean + /** + * Order of this action in the list of actions. A greater number will be shown + * first. If no order specified, actions will be sorted based on their + * position in the category definition. + */ + order?: number // Hook to get default fields for form display. useDefaults: UseDefaults // Hook to make function to convert action data to CosmosMsgFor_Empty. From b0a623cc714090efeddf6e5bfc14cdfbdf779475 Mon Sep 17 00:00:00 2001 From: Noah Saso Date: Thu, 14 Mar 2024 17:42:34 +0100 Subject: [PATCH 4/5] fix code IDs --- packages/utils/constants/chains.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/utils/constants/chains.ts b/packages/utils/constants/chains.ts index b45557e6e2..2fc09b8f03 100644 --- a/packages/utils/constants/chains.ts +++ b/packages/utils/constants/chains.ts @@ -898,7 +898,7 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 2631, CwTokenSwap: 2632, - CwTokenfactoryIssuer: 2633, + CwTokenfactoryIssuerOsmosis: 2633, CwVesting: 2634, DaoCore: 2635, DaoMigrator: -1, @@ -1030,7 +1030,7 @@ export const SUPPORTED_CHAINS: SupportedChainConfig[] = [ // ContractVersion.V240 CwPayrollFactory: 1550, CwTokenSwap: 1551, - CwTokenfactoryIssuer: 1552, + CwTokenfactoryIssuerOsmosis: 1552, CwVesting: 1553, DaoCore: 1554, DaoMigrator: -1, From ef6853f82817eeb79fbdcc5ae024ebfec9646ccd Mon Sep 17 00:00:00 2001 From: Noah Saso Date: Fri, 15 Mar 2024 16:22:39 +0100 Subject: [PATCH 5/5] added migaloo migration to top of commonly used actions for DAOs that need to use it --- .../adapters/DaoVotingTokenStaked/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts index 216db0fb5f..7d21353f09 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/index.ts @@ -52,6 +52,11 @@ export const DaoVotingTokenStakedAdapter: VotingModuleAdapter = { // Functions fields: { actionCategoryMakers: [ + () => ({ + // Add to Commonly Used category. + key: ActionCategoryKey.CommonlyUsed, + actionMakers: [makeMigrateMigalooV4TokenFactoryAction], + }), () => ({ // Add to DAO Governance category. key: ActionCategoryKey.DaoGovernance,