From 898f16fe805d1ceba85e0c21dd7184da245bd7db Mon Sep 17 00:00:00 2001 From: Noah Saso Date: Tue, 26 Nov 2024 02:24:32 -0800 Subject: [PATCH] added plausible events for common actions --- .../stateful/components/dao/CreateDaoForm.tsx | 14 ++- .../stateful/hooks/useProposalActionState.tsx | 54 ++++++++---- .../common/components/NewProposal.tsx | 36 ++++++-- .../DaoProposalMultiple/hooks/useCastVote.ts | 15 ++++ .../common/components/NewProposal.tsx | 36 ++++++-- .../DaoProposalSingle/hooks/useCastVote.ts | 15 ++++ .../components/ProfileCardMemberInfo.tsx | 30 +++++-- .../components/StakingModal.tsx | 48 +++++++++-- .../components/ProfileCardMemberInfo.tsx | 32 ++++--- .../components/StakingModal.tsx | 29 ++++++- .../components/ProfileCardMemberInfo.tsx | 30 +++++-- .../components/StakingModal.tsx | 23 +++++ .../components/ProfileCardMemberInfo.tsx | 37 +++++++- .../components/ProfileCardMemberInfo.tsx | 40 ++++++--- .../components/StakingModal.tsx | 46 ++++++++-- .../components/StakingModal.tsx | 25 +++++- packages/types/plausible.ts | 85 +++++++++++++++++++ 17 files changed, 506 insertions(+), 89 deletions(-) diff --git a/packages/stateful/components/dao/CreateDaoForm.tsx b/packages/stateful/components/dao/CreateDaoForm.tsx index e641882ed..a2bb80232 100644 --- a/packages/stateful/components/dao/CreateDaoForm.tsx +++ b/packages/stateful/components/dao/CreateDaoForm.tsx @@ -5,6 +5,7 @@ import clsx from 'clsx' import cloneDeep from 'lodash.clonedeep' import merge from 'lodash.merge' import { nanoid } from 'nanoid' +import { usePlausible } from 'next-plausible' import { useEffect, useMemo, useState } from 'react' import { FormProvider, @@ -53,6 +54,7 @@ import { DaoTabId, GovernanceProposalActionData, NewDao, + PlausibleEvents, ProposalModuleAdapter, SecretModuleInstantiateInfo, } from '@dao-dao/types' @@ -177,6 +179,7 @@ export const InnerCreateDaoForm = ({ const { t } = useTranslation() const dao = useDaoIfAvailable() const queryClient = useQueryClient() + const plausible = usePlausible() const chainContext = useSupportedChainContext() const { @@ -777,7 +780,7 @@ export const InnerCreateDaoForm = ({ ], } as Partial), }) - } else if (isWalletConnected) { + } else if (isWalletConnected && walletAddress) { setCreating(true) try { const coreAddress = await toast.promise(doCreateDao(), { @@ -801,6 +804,15 @@ export const InnerCreateDaoForm = ({ }, }) + plausible('daoCreate', { + props: { + chainId, + dao: coreAddress, + daoType: values.creator.id, + walletAddress, + }, + }) + const { info } = await queryClient .fetchQuery( contractQueries.info(queryClient, { diff --git a/packages/stateful/hooks/useProposalActionState.tsx b/packages/stateful/hooks/useProposalActionState.tsx index 4f89521b9..73483c11e 100644 --- a/packages/stateful/hooks/useProposalActionState.tsx +++ b/packages/stateful/hooks/useProposalActionState.tsx @@ -3,6 +3,7 @@ import { toUtf8 } from '@cosmjs/encoding' import { OfflineSigner } from '@cosmjs/proto-signing' import { CancelOutlined, Key, Send } from '@mui/icons-material' import { useQueryClient } from '@tanstack/react-query' +import { usePlausible } from 'next-plausible' import { useCallback, useEffect, useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -16,12 +17,12 @@ import { ProposalCrossChainRelayStatus, ProposalStatusAndInfoProps, TextInput, - useConfiguredChainContext, useDao, } from '@dao-dao/stateless' import { ChainId, LoadingData, + PlausibleEvents, PreProposeModuleType, ProposalStatusEnum, ProposalStatusKey, @@ -72,14 +73,8 @@ export const useProposalActionState = ({ onCloseSuccess, }: UseProposalActionStateOptions): UseProposalActionStateReturn => { const { t } = useTranslation() - const { - chain: { chainId, chainName }, - } = useConfiguredChainContext() const queryClient = useQueryClient() - const { - coreAddress, - info: { items }, - } = useDao() + const dao = useDao() const { options: { proposalNumber }, proposalModule, @@ -92,10 +87,11 @@ export const useProposalActionState = ({ getOfflineSigner, } = useWallet() const { isMember = false } = useMembership() + const plausible = usePlausible() const config = useRecoilValue( DaoProposalSingleCommonSelectors.configSelector({ - chainId, + chainId: proposalModule.chainId, contractAddress: proposalModule.address, }) ) @@ -113,7 +109,7 @@ export const useProposalActionState = ({ // execution transaction, unless a memo is already set in the metadata. const allowMemoOnExecute = metadata?.memo ? false - : !!items[DAO_CORE_ALLOW_MEMO_ON_EXECUTE_ITEM_KEY] + : !!dao.info.items[DAO_CORE_ALLOW_MEMO_ON_EXECUTE_ITEM_KEY] const [memo, setMemo] = useState('') const onExecute = useCallback(async () => { @@ -144,9 +140,11 @@ export const useProposalActionState = ({ signingClientGetter = async () => await SigningCosmWasmClient.connectWithSigner( - getRpcForChainId(chainId), + getRpcForChainId(proposalModule.chainId), signer, - makeGetSignerOptions(queryClient)(chainName) + makeGetSignerOptions(queryClient)( + proposalModule.dao.chain.chainName + ) ) } catch (err) { console.error( @@ -178,6 +176,17 @@ export const useProposalActionState = ({ ), }) + plausible('daoProposalExecute', { + props: { + chainId: dao.chainId, + dao: dao.coreAddress, + walletAddress, + proposalModule: proposalModule.address, + proposalModuleType: proposalModule.contractName, + proposalNumber: proposalNumber, + }, + }) + await onExecuteSuccess() } catch (err) { console.error(err) @@ -200,10 +209,10 @@ export const useProposalActionState = ({ onExecuteSuccess, getOfflineSignerDirect, getOfflineSigner, - chainId, queryClient, - chainName, t, + plausible, + dao, ]) const onClose = useCallback(async () => { @@ -220,6 +229,17 @@ export const useProposalActionState = ({ sender: walletAddress, }) + plausible('daoProposalClose', { + props: { + chainId: dao.chainId, + dao: dao.coreAddress, + walletAddress, + proposalModule: proposalModule.address, + proposalModuleType: proposalModule.contractName, + proposalNumber: proposalNumber, + }, + }) + await onCloseSuccess() } catch (err) { console.error(err) @@ -237,6 +257,8 @@ export const useProposalActionState = ({ getSigningClient, walletAddress, onCloseSuccess, + plausible, + dao, ]) const showRelayStatus = @@ -269,8 +291,8 @@ export const useProposalActionState = ({ : statusKey === ProposalStatusEnum.Rejected && // Don't show for Neutron overrule proposals. !( - chainId === ChainId.NeutronMainnet && - coreAddress === NEUTRON_GOVERNANCE_DAO && + dao.chainId === ChainId.NeutronMainnet && + dao.coreAddress === NEUTRON_GOVERNANCE_DAO && proposalModule.prePropose?.type === PreProposeModuleType.NeutronOverruleSingle ) diff --git a/packages/stateful/proposal-module-adapter/adapters/DaoProposalMultiple/common/components/NewProposal.tsx b/packages/stateful/proposal-module-adapter/adapters/DaoProposalMultiple/common/components/NewProposal.tsx index a599189ec..8bf4ba1b8 100644 --- a/packages/stateful/proposal-module-adapter/adapters/DaoProposalMultiple/common/components/NewProposal.tsx +++ b/packages/stateful/proposal-module-adapter/adapters/DaoProposalMultiple/common/components/NewProposal.tsx @@ -1,4 +1,5 @@ import { FlagOutlined, Timelapse } from '@mui/icons-material' +import { usePlausible } from 'next-plausible' import { useFormContext } from 'react-hook-form' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -15,10 +16,13 @@ import { NewProposalProps as StatelessNewProposalProps, useActionsContext, useCachedLoadable, - useChain, useDao, } from '@dao-dao/stateless' -import { BaseNewProposalProps, IProposalModuleBase } from '@dao-dao/types' +import { + BaseNewProposalProps, + IProposalModuleBase, + PlausibleEvents, +} from '@dao-dao/types' import { MAX_NUM_PROPOSAL_CHOICES, convertExpirationToDate, @@ -52,14 +56,13 @@ export const NewProposal = ({ ...props }: NewProposalProps) => { const { t } = useTranslation() - const { chainId } = useChain() const { name: daoName, imageUrl: daoImageUrl, coreAddress, info: { isActive, activeThreshold }, } = useDao() - const { isWalletConnecting, isWalletConnected, getStargateClient } = + const { address, isWalletConnecting, isWalletConnected, getStargateClient } = useWallet() const { watch } = useFormContext() @@ -73,7 +76,7 @@ export const NewProposal = ({ // re-renders. const pauseInfo = useCachedLoadable( DaoDaoCoreSelectors.pauseInfoSelector({ - chainId, + chainId: proposalModule.chainId, contractAddress: coreAddress, params: [], }) @@ -86,7 +89,7 @@ export const NewProposal = ({ const blocksPerYearLoadable = useRecoilValueLoadable( blocksPerYearSelector({ - chainId, + chainId: proposalModule.chainId, }) ) @@ -98,10 +101,11 @@ export const NewProposal = ({ simulationBypassExpiration, } = usePublishProposal() + const plausible = usePlausible() const createProposal = useRecoilCallback( ({ snapshot }) => async (newProposalData: NewProposalData) => { - if (!isWalletConnected) { + if (!isWalletConnected || !address) { toast.error(t('error.logInToContinue')) return } @@ -122,6 +126,19 @@ export const NewProposal = ({ } ) + plausible('daoProposalCreate', { + props: { + chainId: proposalModule.chainId, + dao: proposalModule.dao.coreAddress, + walletAddress: address, + proposalModule: proposalModule.address, + proposalModuleType: proposalModule.contractName, + proposalNumber, + proposalId, + approval: false, + }, + }) + const proposalInfo = await makeGetProposalInfo({ chain: proposalModule.dao.chain, coreAddress: proposalModule.dao.coreAddress, @@ -141,7 +158,7 @@ export const NewProposal = ({ const proposal = ( await snapshot.getPromise( DaoProposalMultipleSelectors.proposalSelector({ - chainId, + chainId: proposalModule.chainId, contractAddress: proposalModule.address, params: [ { @@ -204,12 +221,13 @@ export const NewProposal = ({ proposalModule, blocksPerYearLoadable, getStargateClient, - chainId, processQ, onCreateSuccess, daoName, coreAddress, daoImageUrl, + plausible, + address, ] ) diff --git a/packages/stateful/proposal-module-adapter/adapters/DaoProposalMultiple/hooks/useCastVote.ts b/packages/stateful/proposal-module-adapter/adapters/DaoProposalMultiple/hooks/useCastVote.ts index ea79d81e1..16beee704 100644 --- a/packages/stateful/proposal-module-adapter/adapters/DaoProposalMultiple/hooks/useCastVote.ts +++ b/packages/stateful/proposal-module-adapter/adapters/DaoProposalMultiple/hooks/useCastVote.ts @@ -1,6 +1,8 @@ +import { usePlausible } from 'next-plausible' import { useCallback, useEffect, useState } from 'react' import toast from 'react-hot-toast' +import { PlausibleEvents } from '@dao-dao/types' import { MultipleChoiceVote } from '@dao-dao/types/contracts/DaoProposalMultiple' import { processError } from '@dao-dao/utils' @@ -18,6 +20,7 @@ export const useCastVote = (onSuccess?: () => void | Promise) => { address: walletAddress = '', getSigningClient, } = useWallet() + const plausible = usePlausible() const [castingVote, setCastingVote] = useState(false) @@ -49,6 +52,17 @@ export const useCastVote = (onSuccess?: () => void | Promise) => { sender: walletAddress, }) + plausible('daoProposalVote', { + props: { + chainId: proposalModule.chainId, + dao: proposalModule.dao.coreAddress, + walletAddress, + proposalModule: proposalModule.address, + proposalModuleType: proposalModule.contractName, + proposalNumber, + }, + }) + await onSuccess?.() } catch (err) { console.error(err) @@ -67,6 +81,7 @@ export const useCastVote = (onSuccess?: () => void | Promise) => { getSigningClient, walletAddress, onSuccess, + plausible, ] ) diff --git a/packages/stateful/proposal-module-adapter/adapters/DaoProposalSingle/common/components/NewProposal.tsx b/packages/stateful/proposal-module-adapter/adapters/DaoProposalSingle/common/components/NewProposal.tsx index af9a70112..e40c3f4ad 100644 --- a/packages/stateful/proposal-module-adapter/adapters/DaoProposalSingle/common/components/NewProposal.tsx +++ b/packages/stateful/proposal-module-adapter/adapters/DaoProposalSingle/common/components/NewProposal.tsx @@ -1,4 +1,5 @@ import { BookOutlined, FlagOutlined, Timelapse } from '@mui/icons-material' +import { usePlausible } from 'next-plausible' import { useFormContext } from 'react-hook-form' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -15,11 +16,14 @@ import { NewProposalProps as StatelessNewProposalProps, useActionsContext, useCachedLoadable, - useChain, useDao, useProcessTQ, } from '@dao-dao/stateless' -import { BaseNewProposalProps, IProposalModuleBase } from '@dao-dao/types' +import { + BaseNewProposalProps, + IProposalModuleBase, + PlausibleEvents, +} from '@dao-dao/types' import { convertExpirationToDate, dateToWdhms, @@ -51,14 +55,13 @@ export const NewProposal = ({ ...props }: NewProposalProps) => { const { t } = useTranslation() - const { chainId } = useChain() const { name: daoName, imageUrl: daoImageUrl, coreAddress, info: { isActive, activeThreshold }, } = useDao() - const { isWalletConnecting, isWalletConnected, getStargateClient } = + const { address, isWalletConnecting, isWalletConnected, getStargateClient } = useWallet() const { watch } = useFormContext() @@ -71,7 +74,7 @@ export const NewProposal = ({ // re-renders. const pauseInfo = useCachedLoadable( DaoDaoCoreSelectors.pauseInfoSelector({ - chainId, + chainId: proposalModule.chainId, contractAddress: coreAddress, params: [], }) @@ -84,7 +87,7 @@ export const NewProposal = ({ const blocksPerYearLoadable = useRecoilValueLoadable( blocksPerYearSelector({ - chainId, + chainId: proposalModule.chainId, }) ) @@ -96,10 +99,11 @@ export const NewProposal = ({ simulationBypassExpiration, } = usePublishProposal() + const plausible = usePlausible() const createProposal = useRecoilCallback( ({ snapshot }) => async (newProposalData: NewProposalData) => { - if (!isWalletConnected) { + if (!isWalletConnected || !address) { toast.error(t('error.logInToContinue')) return } @@ -118,6 +122,19 @@ export const NewProposal = ({ failedSimulationBypassSeconds: 3, }) + plausible('daoProposalCreate', { + props: { + chainId: proposalModule.chainId, + dao: proposalModule.dao.coreAddress, + walletAddress: address, + proposalModule: proposalModule.address, + proposalModuleType: proposalModule.contractName, + proposalNumber, + proposalId, + approval: isPreProposeApprovalProposal, + }, + }) + // Get proposal info to display card. const proposalInfo = await makeGetProposalInfo({ chain: proposalModule.dao.chain, @@ -137,7 +154,7 @@ export const NewProposal = ({ const config = await snapshot.getPromise( DaoProposalSingleCommonSelectors.configSelector({ - chainId, + chainId: proposalModule.chainId, contractAddress: proposalModule.address, }) ) @@ -201,13 +218,14 @@ export const NewProposal = ({ proposalModule, blocksPerYearLoadable, getStargateClient, - chainId, processTQ, onCreateSuccess, t, daoName, coreAddress, daoImageUrl, + plausible, + address, ] ) diff --git a/packages/stateful/proposal-module-adapter/adapters/DaoProposalSingle/hooks/useCastVote.ts b/packages/stateful/proposal-module-adapter/adapters/DaoProposalSingle/hooks/useCastVote.ts index aadfe1566..855760bf5 100644 --- a/packages/stateful/proposal-module-adapter/adapters/DaoProposalSingle/hooks/useCastVote.ts +++ b/packages/stateful/proposal-module-adapter/adapters/DaoProposalSingle/hooks/useCastVote.ts @@ -1,6 +1,8 @@ +import { usePlausible } from 'next-plausible' import { useCallback, useEffect, useState } from 'react' import toast from 'react-hot-toast' +import { PlausibleEvents } from '@dao-dao/types' import { Vote } from '@dao-dao/types/contracts/DaoProposalSingle.common' import { processError } from '@dao-dao/utils' @@ -18,6 +20,7 @@ export const useCastVote = (onSuccess?: () => void | Promise) => { address: walletAddress = '', getSigningClient, } = useWallet() + const plausible = usePlausible() const [castingVote, setCastingVote] = useState(false) @@ -49,6 +52,17 @@ export const useCastVote = (onSuccess?: () => void | Promise) => { sender: walletAddress, }) + plausible('daoProposalVote', { + props: { + chainId: proposalModule.chainId, + dao: proposalModule.dao.coreAddress, + walletAddress, + proposalModule: proposalModule.address, + proposalModuleType: proposalModule.contractName, + proposalNumber, + }, + }) + await onSuccess?.() } catch (err) { console.error(err) @@ -67,6 +81,7 @@ export const useCastVote = (onSuccess?: () => void | Promise) => { getSigningClient, walletAddress, onSuccess, + plausible, ] ) diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingCw20Staked/components/ProfileCardMemberInfo.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingCw20Staked/components/ProfileCardMemberInfo.tsx index c8c398a8c..57f5a644c 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingCw20Staked/components/ProfileCardMemberInfo.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingCw20Staked/components/ProfileCardMemberInfo.tsx @@ -1,3 +1,4 @@ +import { usePlausible } from 'next-plausible' import { useCallback, useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -10,9 +11,10 @@ import { blocksPerYearSelector, stakingLoadingAtom, } from '@dao-dao/state' -import { useCachedLoadable, useChain, useDao } from '@dao-dao/stateless' +import { useCachedLoadable, useDao } from '@dao-dao/stateless' import { BaseProfileCardMemberInfoProps, + PlausibleEvents, UnstakingTask, UnstakingTaskStatus, } from '@dao-dao/types' @@ -37,13 +39,13 @@ export const ProfileCardMemberInfo = ({ ...props }: BaseProfileCardMemberInfoProps) => { const { t } = useTranslation() - const { chainId } = useChain() - const { name: daoName } = useDao() + const { chainId, coreAddress, name: daoName, votingModule } = useDao() const { - address: walletAddress, + address: walletAddress = '', isWalletConnected, refreshBalances, } = useWallet() + const plausible = usePlausible() const [showStakingModal, setShowStakingModal] = useState(false) const [claimingLoading, setClaimingLoading] = useState(false) @@ -95,11 +97,11 @@ export const ProfileCardMemberInfo = ({ const doClaim = Cw20StakeHooks.useClaim({ contractAddress: stakingContractToExecute, - sender: walletAddress ?? '', + sender: walletAddress, }) const doOraichainUnbond = OraichainCw20StakingHooks.useUnbond({ contractAddress: stakingContractToExecute, - sender: walletAddress ?? '', + sender: walletAddress, }) const awaitNextBlock = useAwaitNextBlock() @@ -123,6 +125,16 @@ export const ProfileCardMemberInfo = ({ await doClaim() } + plausible('daoVotingClaim', { + props: { + chainId, + dao: coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -149,6 +161,12 @@ export const ProfileCardMemberInfo = ({ sumClaimsAvailable, t, isOraichainCustomStaking, + plausible, + chainId, + coreAddress, + walletAddress, + votingModule.address, + votingModule.contractName, awaitNextBlock, refreshBalances, refreshTotals, diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingCw20Staked/components/StakingModal.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingCw20Staked/components/StakingModal.tsx index e601b3c92..806210660 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingCw20Staked/components/StakingModal.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingCw20Staked/components/StakingModal.tsx @@ -1,3 +1,4 @@ +import { usePlausible } from 'next-plausible' import { useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -22,7 +23,11 @@ import { useCachedLoadable, useVotingModule, } from '@dao-dao/stateless' -import { BaseStakingModalProps, StakingMode } from '@dao-dao/types' +import { + BaseStakingModalProps, + PlausibleEvents, + StakingMode, +} from '@dao-dao/types' import { encodeJsonToBase64, processError } from '@dao-dao/utils' import { SuspenseLoader } from '../../../../components' @@ -51,11 +56,12 @@ const InnerStakingModal = ({ }: BaseStakingModalProps) => { const { t } = useTranslation() const { - address: walletAddress, + address: walletAddress = '', isWalletConnected, refreshBalances, } = useWallet() const votingModule = useVotingModule() + const plausible = usePlausible() const [stakingLoading, setStakingLoading] = useRecoilState(stakingLoadingAtom) @@ -130,19 +136,19 @@ const InnerStakingModal = ({ const doCw20SendAndExecute = Cw20BaseHooks.useSend({ contractAddress: governanceToken.denomOrAddress, - sender: walletAddress ?? '', + sender: walletAddress, }) const doUnstake = Cw20StakeHooks.useUnstake({ contractAddress: stakingContractToExecute, - sender: walletAddress ?? '', + sender: walletAddress, }) const doOraichainUnbond = OraichainCw20StakingHooks.useUnbond({ contractAddress: stakingContractToExecute, - sender: walletAddress ?? '', + sender: walletAddress, }) const doClaim = Cw20StakeHooks.useClaim({ contractAddress: stakingContractToExecute, - sender: walletAddress ?? '', + sender: walletAddress, }) const setRefreshDaoVotingPower = useSetRecoilState( @@ -176,6 +182,16 @@ const InnerStakingModal = ({ }), }) + plausible('daoVotingStake', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -249,6 +265,16 @@ const InnerStakingModal = ({ }) } + plausible('daoVotingUnstake', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -296,6 +322,16 @@ const InnerStakingModal = ({ await doClaim() } + plausible('daoVotingClaim', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingCw721Staked/components/ProfileCardMemberInfo.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingCw721Staked/components/ProfileCardMemberInfo.tsx index bffc8f4e7..46d5fef46 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingCw721Staked/components/ProfileCardMemberInfo.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingCw721Staked/components/ProfileCardMemberInfo.tsx @@ -1,3 +1,4 @@ +import { usePlausible } from 'next-plausible' import { useCallback, useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -9,15 +10,11 @@ import { blocksPerYearSelector, stakingLoadingAtom, } from '@dao-dao/state' -import { - useCachedLoadable, - useChain, - useDao, - useUpdatingRef, -} from '@dao-dao/stateless' +import { useCachedLoadable, useDao, useUpdatingRef } from '@dao-dao/stateless' import { BaseProfileCardMemberInfoProps, Feature, + PlausibleEvents, UnstakingTask, UnstakingTaskStatus, } from '@dao-dao/types' @@ -39,10 +36,9 @@ export const ProfileCardMemberInfo = ({ ...props }: BaseProfileCardMemberInfoProps) => { const { t } = useTranslation() - const { chainId } = useChain() - const { name: daoName, votingModule } = useDao() + const { chainId, name: daoName, coreAddress, votingModule } = useDao() const { - address: walletAddress, + address: walletAddress = '', isWalletConnected, refreshBalances, getSigningClient, @@ -50,6 +46,7 @@ export const ProfileCardMemberInfo = ({ const [showStakingModal, setShowStakingModal] = useState(false) const [claimingLoading, setClaimingLoading] = useState(false) const stakingLoading = useRecoilValue(stakingLoadingAtom) + const plausible = usePlausible() const { collectionInfo, @@ -137,6 +134,16 @@ export const ProfileCardMemberInfo = ({ ], }) + plausible('daoVotingClaim', { + props: { + chainId, + dao: coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -161,16 +168,21 @@ export const ProfileCardMemberInfo = ({ }, [ isWalletConnected, walletAddress, + claimsAvailableRef, t, getSigningClient, votingModule.version, + votingModule.address, + votingModule.contractName, stakingContractAddress, + plausible, + chainId, + coreAddress, awaitNextBlock, refreshBalances, refreshTotals, refreshClaims, collectionInfo.symbol, - claimsAvailableRef, ]) const blockHeightLoadable = useCachedLoadable( diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingCw721Staked/components/StakingModal.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingCw721Staked/components/StakingModal.tsx index 809d3e7c9..b534e85e4 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingCw721Staked/components/StakingModal.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingCw721Staked/components/StakingModal.tsx @@ -1,3 +1,4 @@ +import { usePlausible } from 'next-plausible' import { useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -17,6 +18,7 @@ import { BaseStakingModalProps, LazyNftCardInfo, LoadingDataWithError, + PlausibleEvents, StakingMode, } from '@dao-dao/types' import { getNftKey, processError } from '@dao-dao/utils' @@ -45,7 +47,8 @@ const InnerStakingModal = ({ }: BaseStakingModalProps) => { const { t } = useTranslation() const votingModule = useVotingModule() - const { address: walletAddress, isWalletConnected } = useWallet() + const { address: walletAddress = '', isWalletConnected } = useWallet() + const plausible = usePlausible() const setRefreshWalletNftsId = useSetRecoilState( refreshWalletBalancesIdAtom(walletAddress) @@ -84,11 +87,11 @@ const InnerStakingModal = ({ const doStakeMultiple = Cw721BaseHooks.useSendNftMultiple({ contractAddress: collectionAddress, - sender: walletAddress ?? '', + sender: walletAddress, }) const doUnstake = DaoVotingCw721StakedHooks.useUnstake({ contractAddress: stakingContractAddress, - sender: walletAddress ?? '', + sender: walletAddress, }) const setRefreshDaoVotingPower = useSetRecoilState( @@ -117,6 +120,16 @@ const InnerStakingModal = ({ tokenIds: stakeTokenIds, }) + plausible('daoVotingStake', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -151,6 +164,16 @@ const InnerStakingModal = ({ tokenIds: unstakeTokenIds, }) + plausible('daoVotingUnstake', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingOnftStaked/components/ProfileCardMemberInfo.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingOnftStaked/components/ProfileCardMemberInfo.tsx index 52185ad77..f2027bee1 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingOnftStaked/components/ProfileCardMemberInfo.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingOnftStaked/components/ProfileCardMemberInfo.tsx @@ -1,3 +1,4 @@ +import { usePlausible } from 'next-plausible' import { useCallback, useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -9,15 +10,11 @@ import { blocksPerYearSelector, stakingLoadingAtom, } from '@dao-dao/state' -import { - useCachedLoadable, - useChain, - useDao, - useUpdatingRef, -} from '@dao-dao/stateless' +import { useCachedLoadable, useDao, useUpdatingRef } from '@dao-dao/stateless' import { BaseProfileCardMemberInfoProps, Feature, + PlausibleEvents, UnstakingTask, UnstakingTaskStatus, } from '@dao-dao/types' @@ -39,16 +36,16 @@ export const ProfileCardMemberInfo = ({ ...props }: BaseProfileCardMemberInfoProps) => { const { t } = useTranslation() - const { chainId } = useChain() - const { name: daoName, votingModule } = useDao() + const { chainId, coreAddress, name: daoName, votingModule } = useDao() const { - address: walletAddress, + address: walletAddress = '', isWalletConnected, getSigningClient, } = useWallet() const [showStakingModal, setShowStakingModal] = useState(false) const [claimingLoading, setClaimingLoading] = useState(false) const stakingLoading = useRecoilValue(stakingLoadingAtom) + const plausible = usePlausible() const { collectionInfo, @@ -136,6 +133,16 @@ export const ProfileCardMemberInfo = ({ ], }) + plausible('daoVotingClaim', { + props: { + chainId, + dao: coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -163,7 +170,12 @@ export const ProfileCardMemberInfo = ({ t, getSigningClient, votingModule.version, + votingModule.address, + votingModule.contractName, stakingContractAddress, + plausible, + chainId, + coreAddress, awaitNextBlock, refreshTotals, refreshClaims, diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingOnftStaked/components/StakingModal.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingOnftStaked/components/StakingModal.tsx index 041d87ce9..0c2dab3f0 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingOnftStaked/components/StakingModal.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingOnftStaked/components/StakingModal.tsx @@ -1,4 +1,5 @@ import { toUtf8 } from '@cosmjs/encoding' +import { usePlausible } from 'next-plausible' import { useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -10,6 +11,7 @@ import { BaseStakingModalProps, LazyNftCardInfo, LoadingDataWithError, + PlausibleEvents, StakingMode, } from '@dao-dao/types' import { MsgExecuteContract } from '@dao-dao/types/protobuf/codegen/cosmwasm/wasm/v1/tx' @@ -51,6 +53,7 @@ const InnerStakingModal = ({ } = useWallet({ chainId: dao.chainId, }) + const plausible = usePlausible() const [mode, setMode] = useState(initialMode) @@ -156,6 +159,16 @@ const InnerStakingModal = ({ CHAIN_GAS_MULTIPLIER ) + plausible('daoVotingStake', { + props: { + chainId: dao.chainId, + dao: dao.coreAddress, + walletAddress, + votingModule: dao.votingModule.address, + votingModuleType: dao.votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -202,6 +215,16 @@ const InnerStakingModal = ({ CHAIN_GAS_MULTIPLIER ) + plausible('daoVotingUnstake', { + props: { + chainId: dao.chainId, + dao: dao.coreAddress, + walletAddress, + votingModule: dao.votingModule.address, + votingModuleType: dao.votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingSgCommunityNft/components/ProfileCardMemberInfo.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingSgCommunityNft/components/ProfileCardMemberInfo.tsx index 143925dd8..ef57c2571 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingSgCommunityNft/components/ProfileCardMemberInfo.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingSgCommunityNft/components/ProfileCardMemberInfo.tsx @@ -1,6 +1,7 @@ import { ArrowOutward, Dangerous, HowToVote } from '@mui/icons-material' import { useQueries, useQueryClient } from '@tanstack/react-query' import clsx from 'clsx' +import { usePlausible } from 'next-plausible' import { useCallback, useEffect, useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -14,6 +15,7 @@ import { Button, useDao } from '@dao-dao/stateless' import { BaseProfileCardMemberInfoProps, LoadingDataWithError, + PlausibleEvents, } from '@dao-dao/types' import { CHAIN_GAS_MULTIPLIER, @@ -35,17 +37,18 @@ export const ProfileCardMemberInfo = ({ const { t } = useTranslation() const dao = useDao() const { - address: walletAddress, + address: walletAddress = '', isWalletConnected, getSigningClient, } = useWallet() const queryClient = useQueryClient() + const plausible = usePlausible() const loadingWalletHasNft = useQueryLoadingDataWithError({ ...daoVotingSgCommunityNftExtraQueries.walletHasNft(queryClient, { chainId: dao.chainId, votingModuleAddress: dao.votingModule.address, - walletAddress: walletAddress || '', + walletAddress, }), enabled: !!walletAddress, }) @@ -54,7 +57,7 @@ export const ProfileCardMemberInfo = ({ chainId: dao.chainId, contractAddress: dao.votingModule.address, args: { - address: walletAddress || '', + address: walletAddress, }, }), enabled: !!walletAddress, @@ -198,6 +201,16 @@ export const ProfileCardMemberInfo = ({ CHAIN_GAS_MULTIPLIER ) + plausible('daoVotingStake', { + props: { + chainId: dao.chainId, + dao: dao.coreAddress, + walletAddress, + votingModule: dao.votingModule.address, + votingModuleType: dao.votingModule.contractName, + }, + }) + // Voting power will not appear until the next block. await awaitNextBlock() @@ -217,6 +230,10 @@ export const ProfileCardMemberInfo = ({ t, getSigningClient, dao.votingModule.address, + dao.votingModule.contractName, + dao.chainId, + dao.coreAddress, + plausible, awaitNextBlock, refreshState, ]) @@ -239,6 +256,16 @@ export const ProfileCardMemberInfo = ({ CHAIN_GAS_MULTIPLIER ) + plausible('daoVotingUnstake', { + props: { + chainId: dao.chainId, + dao: dao.coreAddress, + walletAddress, + votingModule: dao.votingModule.address, + votingModuleType: dao.votingModule.contractName, + }, + }) + // Voting power will not appear until the next block. await awaitNextBlock() @@ -258,6 +285,10 @@ export const ProfileCardMemberInfo = ({ t, getSigningClient, dao.votingModule.address, + dao.votingModule.contractName, + dao.chainId, + dao.coreAddress, + plausible, awaitNextBlock, refreshState, ]) diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/components/ProfileCardMemberInfo.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/components/ProfileCardMemberInfo.tsx index 560c3574f..0be0ddb0d 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/components/ProfileCardMemberInfo.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/components/ProfileCardMemberInfo.tsx @@ -1,3 +1,4 @@ +import { usePlausible } from 'next-plausible' import { useCallback, useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -9,9 +10,10 @@ import { blocksPerYearSelector, stakingLoadingAtom, } from '@dao-dao/state' -import { useCachedLoadable, useDao, useVotingModule } from '@dao-dao/stateless' +import { useCachedLoadable, useDao } from '@dao-dao/stateless' import { BaseProfileCardMemberInfoProps, + PlausibleEvents, UnstakingTask, UnstakingTaskStatus, } from '@dao-dao/types' @@ -35,13 +37,13 @@ export const ProfileCardMemberInfo = ({ ...props }: BaseProfileCardMemberInfoProps) => { const { t } = useTranslation() - const { name: daoName } = useDao() - const votingModule = useVotingModule() + const { chainId, coreAddress, name: daoName, votingModule } = useDao() const { - address: walletAddress, + address: walletAddress = '', isWalletConnected, refreshBalances, } = useWallet() + const plausible = usePlausible() const [showStakingModal, setShowStakingModal] = useState(false) const [claimingLoading, setClaimingLoading] = useState(false) @@ -69,7 +71,7 @@ export const ProfileCardMemberInfo = ({ const doClaim = DaoVotingTokenStakedHooks.useClaim({ contractAddress: votingModule.address, - sender: walletAddress ?? '', + sender: walletAddress, }) const awaitNextBlock = useAwaitNextBlock() @@ -85,6 +87,16 @@ export const ProfileCardMemberInfo = ({ try { await doClaim() + plausible('daoVotingClaim', { + props: { + chainId, + dao: coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -107,16 +119,22 @@ export const ProfileCardMemberInfo = ({ setClaimingLoading(false) } }, [ - awaitNextBlock, isWalletConnected, + sumClaimsAvailable, + t, doClaim, - governanceToken.decimals, - governanceToken.symbol, + plausible, + chainId, + coreAddress, + walletAddress, + votingModule.address, + votingModule.contractName, + awaitNextBlock, refreshBalances, - refreshClaims, refreshTotals, - sumClaimsAvailable, - t, + refreshClaims, + governanceToken.decimals, + governanceToken.symbol, ]) const blockHeightLoadable = useCachedLoadable( diff --git a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/components/StakingModal.tsx b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/components/StakingModal.tsx index a6cee4f04..75ad12097 100644 --- a/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/components/StakingModal.tsx +++ b/packages/stateful/voting-module-adapter/adapters/DaoVotingTokenStaked/components/StakingModal.tsx @@ -1,3 +1,4 @@ +import { usePlausible } from 'next-plausible' import { useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -14,7 +15,11 @@ import { StakingModal as StatelessStakingModal, useVotingModule, } from '@dao-dao/stateless' -import { BaseStakingModalProps, StakingMode } from '@dao-dao/types' +import { + BaseStakingModalProps, + PlausibleEvents, + StakingMode, +} from '@dao-dao/types' import { CHAIN_GAS_MULTIPLIER, processError } from '@dao-dao/utils' import { SuspenseLoader } from '../../../../components' @@ -41,11 +46,12 @@ const InnerStakingModal = ({ }: BaseStakingModalProps) => { const { t } = useTranslation() const { - address: walletAddress, + address: walletAddress = '', isWalletConnected, refreshBalances, } = useWallet() const votingModule = useVotingModule() + const plausible = usePlausible() const [stakingLoading, setStakingLoading] = useRecoilState(stakingLoadingAtom) @@ -68,15 +74,15 @@ const InnerStakingModal = ({ const doStake = DaoVotingTokenStakedHooks.useStake({ contractAddress: votingModule.address, - sender: walletAddress ?? '', + sender: walletAddress, }) const doUnstake = DaoVotingTokenStakedHooks.useUnstake({ contractAddress: votingModule.address, - sender: walletAddress ?? '', + sender: walletAddress, }) const doClaim = DaoVotingTokenStakedHooks.useClaim({ contractAddress: votingModule.address, - sender: walletAddress ?? '', + sender: walletAddress, }) const setRefreshDaoVotingPower = useSetRecoilState( @@ -108,6 +114,16 @@ const InnerStakingModal = ({ amount.toCoins(governanceToken.denomOrAddress) ) + plausible('daoVotingStake', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -144,6 +160,16 @@ const InnerStakingModal = ({ amount: amount.toFixed(0), }) + plausible('daoVotingUnstake', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -183,6 +209,16 @@ const InnerStakingModal = ({ try { await doClaim() + plausible('daoVotingClaim', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() diff --git a/packages/stateful/voting-module-adapter/adapters/NeutronVotingRegistry/components/StakingModal.tsx b/packages/stateful/voting-module-adapter/adapters/NeutronVotingRegistry/components/StakingModal.tsx index 5f3d0986d..13338873c 100644 --- a/packages/stateful/voting-module-adapter/adapters/NeutronVotingRegistry/components/StakingModal.tsx +++ b/packages/stateful/voting-module-adapter/adapters/NeutronVotingRegistry/components/StakingModal.tsx @@ -1,4 +1,5 @@ import { useQueries } from '@tanstack/react-query' +import { usePlausible } from 'next-plausible' import { useCallback, useState } from 'react' import toast from 'react-hot-toast' import { useTranslation } from 'react-i18next' @@ -21,6 +22,7 @@ import { } from '@dao-dao/stateless' import { BaseStakingModalProps, + PlausibleEvents, StakingMode, TokenInputOption, } from '@dao-dao/types' @@ -55,6 +57,7 @@ const InnerStakingModal = ({ const { t } = useTranslation() const { address = '', isWalletConnected, refreshBalances } = useWallet() const votingModule = useVotingModule() + const plausible = usePlausible() const { loadingVaults } = useVotingModuleInfo() const realVaults = @@ -96,7 +99,7 @@ const InnerStakingModal = ({ chainId, type, denomOrAddress, - address: address, + address, }) ) ) @@ -170,6 +173,16 @@ const InnerStakingModal = ({ amount.toCoins(selectedVault.bondToken.denomOrAddress) ) + plausible('daoVotingStake', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress: address, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() @@ -206,6 +219,16 @@ const InnerStakingModal = ({ amount: amount.toFixed(0), }) + plausible('daoVotingUnstake', { + props: { + chainId: votingModule.chainId, + dao: votingModule.dao.coreAddress, + walletAddress: address, + votingModule: votingModule.address, + votingModuleType: votingModule.contractName, + }, + }) + // New balances will not appear until the next block. await awaitNextBlock() diff --git a/packages/types/plausible.ts b/packages/types/plausible.ts index 4b2ddb219..8c0d481ba 100644 --- a/packages/types/plausible.ts +++ b/packages/types/plausible.ts @@ -8,4 +8,89 @@ export type PlausibleEvents = { login: { wallet: string } + /** + * DAO create event. + */ + daoCreate: { + chainId: string + dao: string + daoType: string + walletAddress: string + } + /** + * DAO proposal create event. + */ + daoProposalCreate: { + chainId: string + dao: string + walletAddress: string + proposalModule: string + proposalModuleType: string + proposalNumber: number + proposalId: string + approval: boolean + } + /** + * DAO proposal vote event. + */ + daoProposalVote: { + chainId: string + dao: string + walletAddress: string + proposalModule: string + proposalModuleType: string + proposalNumber: number + } + /** + * DAO proposal execute event. + */ + daoProposalExecute: { + chainId: string + dao: string + walletAddress: string + proposalModule: string + proposalModuleType: string + proposalNumber: number + } + /** + * DAO proposal close event. + */ + daoProposalClose: { + chainId: string + dao: string + walletAddress: string + proposalModule: string + proposalModuleType: string + proposalNumber: number + } + /** + * Stake event. + */ + daoVotingStake: { + chainId: string + dao: string + walletAddress: string + votingModule: string + votingModuleType: string + } + /** + * Unstake event. + */ + daoVotingUnstake: { + chainId: string + dao: string + walletAddress: string + votingModule: string + votingModuleType: string + } + /** + * Claim event. + */ + daoVotingClaim: { + chainId: string + dao: string + walletAddress: string + votingModule: string + votingModuleType: string + } }