diff --git a/src/components/inputs/JuiceListbox.tsx b/src/components/inputs/JuiceListbox.tsx index 305bccb3e2..7a3030fa69 100644 --- a/src/components/inputs/JuiceListbox.tsx +++ b/src/components/inputs/JuiceListbox.tsx @@ -21,6 +21,7 @@ interface JuiceListboxProps { export function JuiceListbox(props: JuiceListboxProps) { const { value, onChange, options, buttonClassName, className, disabled } = props + return (
diff --git a/src/locales/messages.pot b/src/locales/messages.pot index 729634caf8..5b5a2e20d2 100644 --- a/src/locales/messages.pot +++ b/src/locales/messages.pot @@ -2819,6 +2819,9 @@ msgstr "" msgid "Transfer unclaimed {0}" msgstr "" +msgid "Ok" +msgstr "" + msgid "Cannot set payouts because your <0>Total payouts is Zero." msgstr "" @@ -4280,9 +4283,6 @@ msgstr "" msgid "Manage your project's state and ownership" msgstr "" -msgid "Ruleset cycle" -msgstr "" - msgid "The amount of reserved tokens currently available to be distributed to the recipients below." msgstr "" diff --git a/src/packages/v4/components/Create/components/pages/ProjectDetails/ProjectChainSelect.tsx b/src/packages/v4/components/Create/components/pages/ProjectDetails/ProjectChainSelect.tsx deleted file mode 100644 index eff3be8fda..0000000000 --- a/src/packages/v4/components/Create/components/pages/ProjectDetails/ProjectChainSelect.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { JuiceListbox } from 'components/inputs/JuiceListbox' -import { DEFAULT_PROJECT_CHAIN_ID, NETWORKS } from 'constants/networks' -import { JB_CHAINS } from 'juice-sdk-core' -import { JBChainId } from 'juice-sdk-react' - -export const ProjectChainSelect: React.FC< - React.PropsWithChildren<{ - value?: JBChainId - onChange?: (value: JBChainId) => void - }> -> = ({ value, onChange }) => { - const networkOptions = () => - Object.values(JB_CHAINS).map(chain => ({ - label: chain.name, - value: chain.chain.id as JBChainId, - })) - - return ( - { - if (!value) return - onChange?.(value) - }} - options={networkOptions()} - /> - ) -} diff --git a/src/packages/v4/components/Create/components/pages/ProjectDetails/ProjectDetailsPage.tsx b/src/packages/v4/components/Create/components/pages/ProjectDetails/ProjectDetailsPage.tsx index 9711ac02e5..4d963efd14 100644 --- a/src/packages/v4/components/Create/components/pages/ProjectDetails/ProjectDetailsPage.tsx +++ b/src/packages/v4/components/Create/components/pages/ProjectDetails/ProjectDetailsPage.tsx @@ -1,5 +1,6 @@ import { Trans, t } from '@lingui/macro' import { Col, Form, Row } from 'antd' +import { JBChainId, JB_CHAINS } from 'juice-sdk-core' import { V2V3_CURRENCY_ETH, V2V3_CURRENCY_USD, @@ -23,6 +24,7 @@ import { trackFathomGoal } from 'lib/fathom' import Link from 'next/link' import { useLockPageRulesWrapper } from 'packages/v2v3/components/Create/hooks/useLockPageRulesWrapper' import { V2V3CurrencyOption } from 'packages/v2v3/models/currencyOption' +import { ProjectChainSelect } from 'packages/v4/components/ProjectDashboard/ProjectChainSelect' import { useSetCreateFurthestPageReached } from 'redux/hooks/v2v3/useEditingCreateFurthestPageReached' import { inputIsLengthRule } from 'utils/antdRules/inputIsLengthRule' import { CreateCollapse } from '../../CreateCollapse/CreateCollapse' @@ -30,7 +32,6 @@ import { OptionalHeader } from '../../OptionalHeader' import { PageContext } from '../../Wizard/contexts/PageContext' import { Wizard } from '../../Wizard/Wizard' import { useProjectDetailsForm } from './hooks/useProjectDetailsForm' -import { ProjectChainSelect } from './ProjectChainSelect' export const ProjectDetailsPage: React.FC< React.PropsWithChildren @@ -46,6 +47,12 @@ export const ProjectDetailsPage: React.FC< const projectOwnerDifferentThanWalletAddress = inputWalletAddress && wallet.userAddress !== inputWalletAddress + + const networkOptions = + Object.values(JB_CHAINS).map(chain => ({ + label: chain.name, + value: chain.chain.id as JBChainId, + })) return (
- + {/* v4TODO: turn into a multiselect */} + 100 diff --git a/src/packages/v4/components/ProjectDashboard/ProjectChainSelect.tsx b/src/packages/v4/components/ProjectDashboard/ProjectChainSelect.tsx new file mode 100644 index 0000000000..b925ce3470 --- /dev/null +++ b/src/packages/v4/components/ProjectDashboard/ProjectChainSelect.tsx @@ -0,0 +1,42 @@ +import { DEFAULT_PROJECT_CHAIN_ID, NETWORKS } from 'constants/networks' +import { JBChainId, useSuckers } from 'juice-sdk-react' + +import { JuiceListbox } from 'components/inputs/JuiceListbox' + +type ChainSelectOption = { + label: string, + value: JBChainId, +} + +export const ProjectChainSelect: React.FC< + React.PropsWithChildren<{ + value?: JBChainId + onChange?: (value: JBChainId) => void + options?: ChainSelectOption[] + }> +> = ({ value, onChange, options }) => { + const { data: suckers } = useSuckers() + const projectAvailableChains = suckers?.map((suckerPair) => ({ + label: NETWORKS[suckerPair.peerChainId].label, + value: suckerPair.peerChainId + })) + + const _options = projectAvailableChains ?? options + + if (!_options) return null + + return ( + { + if (!value) return + onChange?.(value as JBChainId) + }} + options={_options} + /> + ) +} diff --git a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ChainSelectSection.tsx b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ChainSelectSection.tsx index 9e3396d0f6..2f601b0698 100644 --- a/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ChainSelectSection.tsx +++ b/src/packages/v4/components/ProjectDashboard/V4PayRedeemCard/PayProjectModal/components/ChainSelectSection.tsx @@ -79,9 +79,10 @@ export const ChainSelectSection = () => { }} options={networkOptions.map(option => ({ ...option, - label: `${option.label} - Gas: ${ - gasEstimates[option.value] || 'Loading...' - }`, + label: `${option.label}` + // - Gas: ${ + // gasEstimates[option.value] || 'Loading...' + // }`, }))} />
diff --git a/src/packages/v4/hooks/useJBAllRulesetsCrossChain.ts b/src/packages/v4/hooks/useJBAllRulesetsCrossChain.ts new file mode 100644 index 0000000000..fb9793d5b7 --- /dev/null +++ b/src/packages/v4/hooks/useJBAllRulesetsCrossChain.ts @@ -0,0 +1,37 @@ +import { CashOutTaxRate, ReservedPercent, RulesetWeight, WeightCutPercent } from "juice-sdk-core" + +import { useReadJbControllerAllRulesetsOf } from "juice-sdk-react" + +export function useJBAllRulesetsCrossChain({ + projectId, + rulesetNumber +}: { + projectId: bigint + rulesetNumber: bigint +}) { + const { data, isLoading } = useReadJbControllerAllRulesetsOf({ + args: [ + projectId, + rulesetNumber, + 10n, // size (The maximum number of rulesets to return). Arbritrarily set + ] + }) + + if (!data) return { data: undefined, isLoading } + + return { + data: data.map((obj) => ({ + ruleset: { + ...obj.ruleset, + weight: new RulesetWeight(obj.ruleset.weight), + weightCutPercent: new WeightCutPercent(obj.ruleset.weightCutPercent), + }, + metadata: { + ...obj.metadata, + cashOutTaxRate: new CashOutTaxRate(obj.metadata.cashOutTaxRate), + reservedPercent: new ReservedPercent(obj.metadata.reservedPercent) + } + })), + isLoading + } +} diff --git a/src/packages/v4/hooks/useJBRulesetByChain.ts b/src/packages/v4/hooks/useJBRulesetByChain.ts new file mode 100644 index 0000000000..b6dac4544e --- /dev/null +++ b/src/packages/v4/hooks/useJBRulesetByChain.ts @@ -0,0 +1,46 @@ +import { CashOutTaxRate, JBChainId, JBRulesetData, JBRulesetMetadata, ReservedPercent, RulesetWeight, WeightCutPercent } from "juice-sdk-core"; +import { useJBContractContext, useReadJbControllerCurrentRulesetOf } from "juice-sdk-react"; + +import { useProjectIdOfChain } from "./useProjectIdOfChain"; + +export function useJBRulesetByChain(chainId: JBChainId | undefined) { + const { contracts } = useJBContractContext(); + const projectId = useProjectIdOfChain({ chainId }) + const { data, isLoading } = useReadJbControllerCurrentRulesetOf({ + chainId, + address: contracts?.controller?.data ?? undefined, + args: [BigInt(projectId ?? 0)], + query: { + select([ruleset, rulesetMetadata]) { + return [ + { + ...ruleset, + weight: new RulesetWeight(ruleset.weight), + weightCutPercent: new WeightCutPercent(ruleset.weightCutPercent), + }, + { + ...rulesetMetadata, + cashOutTaxRate: new CashOutTaxRate(rulesetMetadata.cashOutTaxRate), + reservedPercent: new ReservedPercent( + rulesetMetadata.reservedPercent + ), + }, + ]; + }, + }, + }); + + if (!chainId) { + return { + ruleset: undefined, + rulesetMetadata: undefined, + isLoading: false, + } + } + + return { + ruleset: data?.[0] as JBRulesetData, + rulesetMetadata: data?.[1] as JBRulesetMetadata, + isLoading, + } +} diff --git a/src/packages/v4/hooks/useJBUpcomingRuleset.ts b/src/packages/v4/hooks/useJBUpcomingRuleset.ts index f2234a9f31..a6f03e94eb 100644 --- a/src/packages/v4/hooks/useJBUpcomingRuleset.ts +++ b/src/packages/v4/hooks/useJBUpcomingRuleset.ts @@ -7,21 +7,29 @@ import { WeightCutPercent, } from 'juice-sdk-core' import { + JBChainId, useJBContractContext, - useReadJbControllerUpcomingRulesetOf, + useReadJbControllerUpcomingRulesetOf } from 'juice-sdk-react' -// @todo: add to SDK -export function useJBUpcomingRuleset(): { +import { useProjectIdOfChain } from './useProjectIdOfChain' + +// @v4todo: add to SDK +export function useJBUpcomingRuleset(chainId?: JBChainId): { ruleset: JBRulesetData | undefined rulesetMetadata: JBRulesetMetadata | undefined isLoading: boolean } { - const { contracts, projectId } = useJBContractContext() + const { contracts, projectId: defaultProjectId } = useJBContractContext() + + const projectId = useProjectIdOfChain({ chainId }) + const { data, isLoading } = useReadJbControllerUpcomingRulesetOf({ address: contracts.controller?.data ?? undefined, - args: [projectId], + args: [BigInt(projectId ?? defaultProjectId)], + chainId }) + const _latestUpcomingRuleset = data?.[0] const _latestUpcomingRulesetMetadata = data?.[1] const upcomingWeight = new RulesetWeight(_latestUpcomingRuleset?.weight ?? 0n) diff --git a/src/packages/v4/hooks/useProjectIdOfChain.ts b/src/packages/v4/hooks/useProjectIdOfChain.ts new file mode 100644 index 0000000000..b95b3ab29e --- /dev/null +++ b/src/packages/v4/hooks/useProjectIdOfChain.ts @@ -0,0 +1,14 @@ +import { JBChainId } from "juice-sdk-core"; +import { useSuckers } from "juice-sdk-react"; + +// Gets the projectId of a project on a given chain +// -> (Project IDs can vary across chains) +export function useProjectIdOfChain({ + chainId +}: { + chainId: JBChainId | undefined +}) { + const { data: suckers } = useSuckers() + + return suckers?.find((suckerPair) => suckerPair.peerChainId === chainId )?.projectId +} diff --git a/src/packages/v4/hooks/useProjectRulesetsDiffAcrossChains.ts b/src/packages/v4/hooks/useProjectRulesetsDiffAcrossChains.ts new file mode 100644 index 0000000000..72896c3fb3 --- /dev/null +++ b/src/packages/v4/hooks/useProjectRulesetsDiffAcrossChains.ts @@ -0,0 +1,40 @@ +import { JBChainId, JBRulesetData, JBRulesetMetadata } from "juice-sdk-core"; +import { useJBContractContext, useSuckers } from "juice-sdk-react"; + + +export function useProjectRulesetsDiffAcrossChains(type: 'upcoming' | 'current') { + const { data: suckers } = useSuckers() + const { projectId, contracts } = useJBContractContext() + + const currentRulesetsAndMetadataByChain = { + // 1234: { + // ruleset: JBRulesetData + // metadata: JBRulesetMetadata + // }, + // etc. + } as Record + const upcomingRulesetsAndMetadataByChain = { + // 1234: { + // ruleset: JBRulesetData + // metadata: JBRulesetMetadata + // }, + // etc. + } + // suckers?.forEach((suckerPair) => { + // const { data: currentRuleset, isLoading: currentLoading } = useJBRuleset(suckerPair.chainId) + // const { data: upcomingRuleset, isLoading: upcomingLoading } = useJBUpcomingRuleset(suckerPair.peerChainId as JBChainId) + // // how to fill currentRulesetsAndMetadataByChain and upcomingRulesetsAndMetadataByChain? + // }) + + // if (type === 'upcoming') { + // return { + // data: getDiffedAttrBetweenRulesets(upcomingRulesetsAndMetadataByChain), + // isLoading + // } + // } + + // return { + // data: getDiffedAttrBetweenRulesets(currentRulesetsAndMetadataByChain), + // isLoading + // } +} diff --git a/src/packages/v4/hooks/useV4PayoutSplits.ts b/src/packages/v4/hooks/useV4CurrentPayoutSplits.ts similarity index 52% rename from src/packages/v4/hooks/useV4PayoutSplits.ts rename to src/packages/v4/hooks/useV4CurrentPayoutSplits.ts index 59650d9728..6650f951f6 100644 --- a/src/packages/v4/hooks/useV4PayoutSplits.ts +++ b/src/packages/v4/hooks/useV4CurrentPayoutSplits.ts @@ -4,21 +4,24 @@ import { SplitPortion } from 'juice-sdk-core' import { - useJBContractContext, + JBChainId, useJBRuleset, useReadJbSplitsSplitsOf, - useReadJbTokensTokenOf, + useReadJbTokensTokenOf } from 'juice-sdk-react' -export const useV4CurrentPayoutSplits = () => { - const { projectId } = useJBContractContext() +import { useProjectIdOfChain } from './useProjectIdOfChain' + +export const useV4CurrentPayoutSplits = (chainId?: JBChainId) => { + const projectId = useProjectIdOfChain({ chainId }) + const { data: tokenAddress } = useReadJbTokensTokenOf() - const { data: ruleset } = useJBRuleset() + const { data: ruleset, isLoading: rulesetIsLoading } = useJBRuleset() const rulesetId = BigInt(ruleset?.id ?? 0) const groupId = BigInt(tokenAddress ?? NATIVE_TOKEN) // contracts say this is: `uint256(uint160(tokenAddress))` - return useReadJbSplitsSplitsOf({ - args: [projectId, rulesetId, groupId], + const { data, isLoading } = useReadJbSplitsSplitsOf({ + args: [BigInt(projectId ?? 0), rulesetId, groupId], query: { select(data) { return data.map( @@ -29,5 +32,10 @@ export const useV4CurrentPayoutSplits = () => { ) }, }, + chainId }) + + if (rulesetIsLoading) return { data: undefined, isLoading: true} + + return { data, isLoading } } diff --git a/src/packages/v4/hooks/useV4ProjectOwnerOf.ts b/src/packages/v4/hooks/useV4ProjectOwnerOf.ts index 3be58bae7e..06fb7ad759 100644 --- a/src/packages/v4/hooks/useV4ProjectOwnerOf.ts +++ b/src/packages/v4/hooks/useV4ProjectOwnerOf.ts @@ -1,10 +1,12 @@ -import { useJBContractContext, useReadJbProjectsOwnerOf } from "juice-sdk-react"; +import { JBChainId } from "juice-sdk-core"; +import { useReadJbProjectsOwnerOf } from "juice-sdk-react"; +import { useProjectIdOfChain } from "./useProjectIdOfChain"; -const useProjectOwnerOf = () => { - const { projectId } = useJBContractContext(); +const useV4ProjectOwnerOf = (chainId?: JBChainId) => { + const projectId = useProjectIdOfChain({ chainId }) const { data: projectOwnerAddress, isLoading } = useReadJbProjectsOwnerOf({ - args: [projectId], + args: [BigInt(projectId ?? 0)], }); return { @@ -13,4 +15,4 @@ const useProjectOwnerOf = () => { }; }; -export default useProjectOwnerOf; +export default useV4ProjectOwnerOf; diff --git a/src/packages/v4/hooks/useV4ReservedSplits.ts b/src/packages/v4/hooks/useV4ReservedSplits.ts index 800586ddee..79e41396c9 100644 --- a/src/packages/v4/hooks/useV4ReservedSplits.ts +++ b/src/packages/v4/hooks/useV4ReservedSplits.ts @@ -1,19 +1,20 @@ -import { JBSplit, SplitPortion } from 'juice-sdk-core' +import { JBChainId, JBSplit, SplitPortion } from 'juice-sdk-core' import { - useJBContractContext, useJBRuleset, - useReadJbSplitsSplitsOf, + useReadJbSplitsSplitsOf } from 'juice-sdk-react' +import { useProjectIdOfChain } from './useProjectIdOfChain' + const RESERVED_SPLITS_GROUP_ID = 1n -export const useV4ReservedSplits = () => { - const { projectId } = useJBContractContext() +export const useV4ReservedSplits = (chainId?: JBChainId) => { + const projectId = useProjectIdOfChain({ chainId }) const { data: ruleset } = useJBRuleset() const { data: _splits, isLoading: currentSplitsLoading } = useReadJbSplitsSplitsOf({ - args: [projectId, BigInt(ruleset?.id ?? 0), RESERVED_SPLITS_GROUP_ID], + args: [BigInt(projectId ?? 0), BigInt(ruleset?.id ?? 0), RESERVED_SPLITS_GROUP_ID], query: { select(data) { return data.map(d => ({ @@ -23,7 +24,7 @@ export const useV4ReservedSplits = () => { }, }, }) - + const splits: JBSplit[] = _splits ? [..._splits] : [] return { splits, isLoading: currentSplitsLoading } diff --git a/src/packages/v4/hooks/useV4UpcomingPayoutSplits.ts b/src/packages/v4/hooks/useV4UpcomingPayoutSplits.ts new file mode 100644 index 0000000000..1ffc236713 --- /dev/null +++ b/src/packages/v4/hooks/useV4UpcomingPayoutSplits.ts @@ -0,0 +1,48 @@ +import { + JBSplit, + NATIVE_TOKEN, + SplitPortion +} from 'juice-sdk-core' +import { + JBChainId, + useReadJbSplitsSplitsOf, + useReadJbTokensTokenOf +} from 'juice-sdk-react' + +import { useJBUpcomingRuleset } from './useJBUpcomingRuleset' +import { useProjectIdOfChain } from './useProjectIdOfChain' + +export const useV4UpcomingPayoutSplits = (chainId?: JBChainId) => { + const projectId = useProjectIdOfChain({ chainId }) + + const { ruleset: upcomingRuleset, isLoading: upcomingRulesetLoading } = + useJBUpcomingRuleset(chainId) + const { data: tokenAddress } = useReadJbTokensTokenOf() + const groupId = BigInt(tokenAddress ?? NATIVE_TOKEN) // contracts say this is: `uint256(uint160(tokenAddress))` + + const { data, isLoading } = useReadJbSplitsSplitsOf({ + args: [ + BigInt(projectId ?? 0), + BigInt(upcomingRuleset?.id ?? 0), + groupId, + ], + query: { + select(data) { + return data.map(d => ({ + ...d, + percent: new SplitPortion(d.percent), + })) + }, + }, + chainId + }) as { data: JBSplit[], isLoading: boolean } + + if (upcomingRulesetLoading) { + return { data: undefined, isLoading: true } + } + + if (!projectId) return { data: undefined, isLoading: false} + + + return { data, isLoading } +} diff --git a/src/packages/v4/hooks/useV4WalletHasPermission.ts b/src/packages/v4/hooks/useV4WalletHasPermission.ts index f68045fd1b..b033f30ac0 100644 --- a/src/packages/v4/hooks/useV4WalletHasPermission.ts +++ b/src/packages/v4/hooks/useV4WalletHasPermission.ts @@ -1,12 +1,13 @@ -import { useWallet } from 'hooks/Wallet' import { useJBContractContext, useReadJbPermissionsHasPermissions, } from 'juice-sdk-react' + +import { useWallet } from 'hooks/Wallet' import { isEqualAddress } from 'utils/address' import { zeroAddress } from 'viem' import { V4OperatorPermission } from '../models/v4Permissions' -import useProjectOwnerOf from './useV4ProjectOwnerOf' +import useV4ProjectOwnerOf from './useV4ProjectOwnerOf' export function useV4WalletHasPermission( permission: V4OperatorPermission | V4OperatorPermission[], @@ -14,7 +15,7 @@ export function useV4WalletHasPermission( const { userAddress } = useWallet() const { projectId } = useJBContractContext() - const { data: projectOwnerAddress } = useProjectOwnerOf() + const { data: projectOwnerAddress } = useV4ProjectOwnerOf() const _operator = userAddress ?? zeroAddress const _account = projectOwnerAddress ?? zeroAddress diff --git a/src/packages/v4/utils/rulesetDiff.ts b/src/packages/v4/utils/rulesetDiff.ts new file mode 100644 index 0000000000..3e3e7becf8 --- /dev/null +++ b/src/packages/v4/utils/rulesetDiff.ts @@ -0,0 +1,40 @@ +import { JBChainId, JBRulesetData, JBRulesetMetadata } from "juice-sdk-core"; + +export function getDiffedAttrBetweenRulesets(rulesetsByChain: Record) { + // Get a list of all attributes we're keeping (diffed attributes) + const diffedRulesetAttrs = Object.keys(Object.values(rulesetsByChain)[0].ruleset).filter((rulesetAttr) => ( + // @ts-ignore + rulesets.slice(1).some(({ ruleset }) => Boolean(ruleset[rulesetAttr] !== rulesets[0][rulesetAttr])) + )) + + const diffedMetadataAttrs = Object.keys(Object.values(rulesetsByChain)[0].metadata).filter((metadataAttr) => ( + // @ts-ignore + rulesets.slice(1).some(({ ruleset }) => Boolean(ruleset[metadataAttr] !== rulesets[0][metadataAttr])) + )) + + if (!diffedRulesetAttrs.length && !diffedMetadataAttrs) return [] + + const rulesetsWithDiffedAttrsOnly = {} as Record> + + Object.keys(rulesetsByChain).map((chainIdStr) => { + const chainId = parseInt(chainIdStr) as JBChainId + const ruleset = rulesetsByChain[chainId].ruleset + const metadata = rulesetsByChain[chainId].metadata + rulesetsWithDiffedAttrsOnly[chainId] = {} + + diffedRulesetAttrs.forEach((rulesetAttr) => { + // @ts-ignore + rulesetsWithDiffedAttrsOnly[chainId][rulesetAttr] = ruleset[rulesetAttr] + }) + + diffedMetadataAttrs.forEach((metadataAttr) => { + // @ts-ignore + rulesetsWithDiffedAttrsOnly[chainId][metadataAttr] = metadata[rulesetAttr] + }) + }) + + return rulesetsWithDiffedAttrsOnly +} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/RulesetCrossChainDiffModal/RulesetCrossChainDiffModal.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/RulesetCrossChainDiffModal/RulesetCrossChainDiffModal.tsx new file mode 100644 index 0000000000..fe5d5101bf --- /dev/null +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/RulesetCrossChainDiffModal/RulesetCrossChainDiffModal.tsx @@ -0,0 +1,24 @@ +import { JBRulesetData, JBRulesetMetadata } from "juice-sdk-core" + +import { t } from "@lingui/macro" +import { JuiceModal } from "components/modals/JuiceModal" + +export function RulesetCrossChainDiffModal({ + open, + setOpen, + rulesetsDiffAcrossChains, +}: { + open: boolean + setOpen: () => void + rulesetsDiffAcrossChains: Partial +}) { + return ( + + + + ) +} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/RulesetCrossChainDiffModal/index.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/RulesetCrossChainDiffModal/index.ts new file mode 100644 index 0000000000..e445fc05aa --- /dev/null +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/RulesetCrossChainDiffModal/index.ts @@ -0,0 +1 @@ +export * from './RulesetCrossChainDiffModal'; diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4CurrentUpcomingSubPanel.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4CurrentUpcomingSubPanel.tsx index fcba8b6663..e62c606e53 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4CurrentUpcomingSubPanel.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4CurrentUpcomingSubPanel.tsx @@ -1,12 +1,16 @@ -import { InformationCircleIcon } from '@heroicons/react/24/outline' import { Trans, t } from '@lingui/macro' + +import { InformationCircleIcon } from '@heroicons/react/24/outline' import { currentCycleRemainingLengthTooltip } from 'components/Project/ProjectTabs/CyclesPayoutsTab/CyclesPanelTooltips' import { UpcomingCycleChangesCallout } from 'components/Project/ProjectTabs/CyclesPayoutsTab/UpcomingCycleChangesCallout' import { TitleDescriptionDisplayCard } from 'components/Project/ProjectTabs/TitleDescriptionDisplayCard' +import { ProjectChainSelect } from 'packages/v4/components/ProjectDashboard/ProjectChainSelect' import { RulesetCountdownProvider } from 'packages/v4/contexts/RulesetCountdownProvider' +import { useState } from 'react' import { twMerge } from 'tailwind-merge' import { useRulesetCountdown } from '../../hooks/useRulesetCountdown' import { useV4CurrentUpcomingSubPanel } from '../../hooks/useV4CurrentUpcomingSubPanel' +import { useCyclesPanelSelectedChain } from './contexts/CyclesPanelSelectedChainContext' import { useV4UpcomingRulesetHasChanges } from './hooks/useV4UpcomingRulesetHasChanges' import { V4ConfigurationDisplayCard } from './V4ConfigurationDisplayCard' import { V4PayoutsSubPanel } from './V4PayoutsSubPanel' @@ -27,8 +31,12 @@ export const V4CurrentUpcomingSubPanel = ({ }: { id: 'current' | 'upcoming' }) => { + const [rulesetCrossChainDiffModalOpen, setRulesetCrossChainDiffModalOpen] = useState(false) + const info = useV4CurrentUpcomingSubPanel(id) const { hasChanges, loading } = useV4UpcomingRulesetHasChanges() + const { selectedChainId, setSelectedChainId } = useCyclesPanelSelectedChain() + // const { data: rulesetsDiffAcrossChains } = useProjectRulesetsDiffAcrossChains({ rulesetNumber: info.rulesetNumber} ) const rulesetLengthTooltip = info.type === 'current' ? currentCycleRemainingLengthTooltip : undefined @@ -77,61 +85,94 @@ export const V4CurrentUpcomingSubPanel = ({ ? t`This ruleset has upcoming changes` : t`This ruleset has no upcoming changes` + const openRulesetCrossChainDiffModal = () => { + setRulesetCrossChainDiffModalOpen(true) + } + return ( -
-
- {id === 'upcoming' && ( - - )} - -
- } - /> - - } - tooltip={rulesetStatusTooltip} - /> - - {info.type === 'current' ? ( - - +
+
+ { selectedChainId ? +
+ setSelectedChainId(chainId)} + /> + {/* { rulesetsDiffAcrossChains?.length ? + This project's other chain instances have different rulesets. openRulesetCrossChainDiffModal()}>See more + } + > + - - } - tooltip={rulesetLengthTooltip} + + : null} */} +
+ : null } +
+
+ {id === 'upcoming' && ( + + )} + +
+ } /> - ) : ( + info.status?.toString() ?? } - tooltip={rulesetLengthTooltip} + tooltip={rulesetStatusTooltip} /> - )} + + {info.type === 'current' ? ( + + + + } + tooltip={rulesetLengthTooltip} + /> + ) : ( + + } + tooltip={rulesetLengthTooltip} + /> + )} +
+ {/* Gets data from useV4CurrentUpcomingConfigurationPanel */} +
- -
- -
+ +
+ {/* setRulesetCrossChainDiffModalOpen(false)} + rulesetsDiffAcrossChains={rulesetsDiffAcrossChains} + /> */} + ) } diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4CyclesPayoutsPanel.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4CyclesPayoutsPanel.tsx index 031f8971b8..f1a46aed5c 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4CyclesPayoutsPanel.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4CyclesPayoutsPanel.tsx @@ -1,5 +1,5 @@ import { Tab } from '@headlessui/react' -import { t, Trans } from '@lingui/macro' +import { t } from '@lingui/macro' import { CyclesTab } from 'components/Project/ProjectTabs/CyclesPayoutsTab/CyclesTab' import { useMemo } from 'react' import { V4CurrentUpcomingSubPanel } from './V4CurrentUpcomingSubPanel' @@ -18,29 +18,30 @@ export const V4CyclesPayoutsPanel = () => { ], [], ) + return ( - -
-

- Ruleset cycle -

- + <> + +
+

Ruleset cycle

+ + {tabs.map(tab => ( + + ))} + +
+ {tabs.map(tab => ( - + + {tab.id === 'history' ? ( + <> // + ) : ( + + )} + ))} -
-
- - {tabs.map(tab => ( - - {tab.id === 'history' ? ( - <> // - ) : ( - - )} - - ))} - -
+ + + ) } diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4DistributePayoutsModal.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4DistributePayoutsModal.tsx index ed88416781..2fa1ee1af7 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4DistributePayoutsModal.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/V4DistributePayoutsModal.tsx @@ -1,4 +1,12 @@ -import { t, Trans } from '@lingui/macro' +import { Trans, t } from '@lingui/macro' +import { NATIVE_TOKEN, NATIVE_TOKEN_DECIMALS } from 'juice-sdk-core' +import { + useJBContractContext, + useWriteJbMultiTerminalSendPayoutsOf, +} from 'juice-sdk-react' +import { V4CurrencyName, V4_CURRENCY_ETH } from 'packages/v4/utils/currency' +import { useContext, useState } from 'react' + import { waitForTransactionReceipt } from '@wagmi/core' import { Form } from 'antd' import InputAccessoryButton from 'components/buttons/InputAccessoryButton' @@ -7,17 +15,10 @@ import FormattedNumberInput from 'components/inputs/FormattedNumberInput' import TransactionModal from 'components/modals/TransactionModal' import { FEES_EXPLANATION } from 'components/strings' import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' -import { NATIVE_TOKEN, NATIVE_TOKEN_DECIMALS } from 'juice-sdk-core' -import { - useJBContractContext, - useWriteJbMultiTerminalSendPayoutsOf, -} from 'juice-sdk-react' import { PayoutsTable } from 'packages/v4/components/PayoutsTable/PayoutsTable' import { usePayoutLimit } from 'packages/v4/hooks/usePayoutLimit' -import { useV4CurrentPayoutSplits } from 'packages/v4/hooks/useV4PayoutSplits' -import { V4_CURRENCY_ETH, V4CurrencyName } from 'packages/v4/utils/currency' +import { useV4CurrentPayoutSplits } from 'packages/v4/hooks/useV4CurrentPayoutSplits' import { wagmiConfig } from 'packages/v4/wagmiConfig' -import { useContext, useState } from 'react' import { emitErrorNotification } from 'utils/notifications' import { parseUnits } from 'viem' import { useV4DistributableAmount } from './hooks/useV4DistributableAmount' diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/contexts/CyclesPanelSelectedChainContext.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/contexts/CyclesPanelSelectedChainContext.tsx new file mode 100644 index 0000000000..ea327ad788 --- /dev/null +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/contexts/CyclesPanelSelectedChainContext.tsx @@ -0,0 +1,48 @@ +import { JBChainId, useJBChainId } from 'juice-sdk-react' +import { createContext, useContext, useEffect } from 'react' + +import { useState } from 'react' + +type CyclesPanelSelectedChainContextType = { + selectedChainId: JBChainId | undefined + setSelectedChainId: (chainId: JBChainId) => void +} + +export const CyclesPanelSelectedChainContext = createContext({ + selectedChainId: 84532, // v4TODO + setSelectedChainId: () => { + console.error('CyclesPanelSelectedChainContext.setSelectedChainId called but no provider set') + }, +}) + +export const CyclesPanelSelectedChainProvider: React.FC> = ({ + children, +}) => { + const [selectedChainId, setSelectedChainId] = useState() + const projectPageChainId = useJBChainId() + + useEffect(() => { + setSelectedChainId(projectPageChainId) + }, [projectPageChainId]) + + return ( + + {children} + + ) +} + +export const useCyclesPanelSelectedChain = () => { + const context = useContext(CyclesPanelSelectedChainContext) + if (!context) { + throw new Error( + 'useCyclesPanelSelectedChain must be used within a CyclesPanelSelectedChainProvider', + ) + } + return context +} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4CurrentUpcomingPayoutSplits.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4CurrentUpcomingPayoutSplits.ts index 409405372a..b8167ff7db 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4CurrentUpcomingPayoutSplits.ts +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4CurrentUpcomingPayoutSplits.ts @@ -1,40 +1,16 @@ -import { JBSplit, SplitPortion } from 'juice-sdk-core' -import { - useJBContractContext, - useReadJbSplitsSplitsOf, - useReadJbTokensTokenOf, -} from 'juice-sdk-react' -import { useJBUpcomingRuleset } from 'packages/v4/hooks/useJBUpcomingRuleset' -import { useV4CurrentPayoutSplits } from 'packages/v4/hooks/useV4PayoutSplits' +import { useV4CurrentPayoutSplits } from 'packages/v4/hooks/useV4CurrentPayoutSplits' +import { useV4UpcomingPayoutSplits } from 'packages/v4/hooks/useV4UpcomingPayoutSplits' +import { useCyclesPanelSelectedChain } from '../contexts/CyclesPanelSelectedChainContext' export const useV4CurrentUpcomingPayoutSplits = ( type: 'current' | 'upcoming', ) => { - const { projectId } = useJBContractContext() - const { data: tokenAddress } = useReadJbTokensTokenOf() + const { selectedChainId } = useCyclesPanelSelectedChain() + const { data: currentSplits, isLoading: currentSplitsLoading } = - useV4CurrentPayoutSplits() + useV4CurrentPayoutSplits(selectedChainId) - const { ruleset: upcomingRuleset, isLoading: upcomingRulesetLoading } = - useJBUpcomingRuleset() - const { data: _upcomingSplits, isLoading: upcomingSplitsLoading } = - useReadJbSplitsSplitsOf({ - args: [ - projectId, - BigInt(upcomingRuleset?.id ?? 0), - BigInt(tokenAddress ?? 0), - ], - query: { - select(data) { - return data.map(d => ({ - ...d, - percent: new SplitPortion(d.percent), - })) - }, - }, - }) - - const upcomingSplits: JBSplit[] = _upcomingSplits ? [..._upcomingSplits] : [] + const { data: upcomingSplits, isLoading: upcomingSplitsLoading } = useV4UpcomingPayoutSplits(selectedChainId) if (type === 'current') { return { splits: currentSplits, isLoading: currentSplitsLoading } @@ -42,6 +18,6 @@ export const useV4CurrentUpcomingPayoutSplits = ( return { splits: upcomingSplits, - isLoading: upcomingSplitsLoading || upcomingRulesetLoading, + isLoading: upcomingSplitsLoading, } } diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4CycleSection.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4CycleSection.ts index e8dcc0f9b7..8ad05cf0b6 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4CycleSection.ts +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4CycleSection.ts @@ -1,16 +1,19 @@ import { ConfigurationPanelTableData } from 'components/Project/ProjectTabs/CyclesPayoutsTab/ConfigurationPanel' -import { useJBRuleset } from 'juice-sdk-react' +import { useJBRulesetByChain } from 'packages/v4/hooks/useJBRulesetByChain' import { useJBUpcomingRuleset } from 'packages/v4/hooks/useJBUpcomingRuleset' import { usePayoutLimit } from 'packages/v4/hooks/usePayoutLimit' import { useUpcomingPayoutLimit } from 'packages/v4/hooks/useUpcomingPayoutLimit' +import { useCyclesPanelSelectedChain } from '../contexts/CyclesPanelSelectedChainContext' import { useV4FormatConfigurationCycleSection } from './useV4FormatConfigurationCycleSection' export const useV4CycleSection = ( type: 'current' | 'upcoming', ): ConfigurationPanelTableData => { - const { data: ruleset } = useJBRuleset() + const { selectedChainId } = useCyclesPanelSelectedChain() + + const { ruleset } = useJBRulesetByChain(selectedChainId) - const { ruleset: upcomingRuleset, isLoading: upcomingRulesetLoading } = useJBUpcomingRuleset() + const { ruleset: upcomingRuleset, isLoading: upcomingRulesetLoading } = useJBUpcomingRuleset(selectedChainId) const { data: payoutLimits } = usePayoutLimit() const payoutLimitAmount = payoutLimits?.amount diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4ExportSplitsToCsv.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4ExportSplitsToCsv.ts index 75a75392ad..e01c626d6d 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4ExportSplitsToCsv.ts +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4ExportSplitsToCsv.ts @@ -1,7 +1,7 @@ import { t } from '@lingui/macro' import { JBSplit } from 'juice-sdk-core' import { useJBContractContext } from 'juice-sdk-react' -import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' +import useV4ProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' import { v4GetProjectOwnerRemainderSplit } from 'packages/v4/utils/v4Splits' import { useState } from 'react' import { downloadCsvFile } from 'utils/csv' @@ -52,7 +52,7 @@ export const useV4ExportSplitsToCsv = ( splitName = 'splits', fcNumber?: number, ) => { - const { data: projectOwnerAddress } = useProjectOwnerOf() + const { data: projectOwnerAddress } = useV4ProjectOwnerOf() const { projectId } = useJBContractContext() const [loading, setLoading] = useState(false) diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4ExtensionSection.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4ExtensionSection.ts index 513d301ef7..d23ae7e612 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4ExtensionSection.ts +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4ExtensionSection.ts @@ -1,15 +1,18 @@ import { ConfigurationPanelTableData } from 'components/Project/ProjectTabs/CyclesPayoutsTab/ConfigurationPanel' -import { useJBRulesetMetadata } from 'juice-sdk-react' +import { useJBRulesetByChain } from 'packages/v4/hooks/useJBRulesetByChain' import { useJBUpcomingRuleset } from 'packages/v4/hooks/useJBUpcomingRuleset' +import { useCyclesPanelSelectedChain } from '../contexts/CyclesPanelSelectedChainContext' import { useV4FormatConfigurationExtensionSection } from './useV4FormatConfigurationExtensionSection' export const useV4ExtensionSection = ( type: 'current' | 'upcoming', ): ConfigurationPanelTableData | null => { - const { data: rulesetMetadata } = useJBRulesetMetadata() + const { selectedChainId } = useCyclesPanelSelectedChain() + + const { rulesetMetadata } = useJBRulesetByChain(selectedChainId) const { rulesetMetadata: upcomingRulesetMetadata, - } = useJBUpcomingRuleset() + } = useJBUpcomingRuleset(selectedChainId) return useV4FormatConfigurationExtensionSection({ diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4OtherRulesSection.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4OtherRulesSection.ts index 9e66568513..87e744723a 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4OtherRulesSection.ts +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4OtherRulesSection.ts @@ -1,15 +1,18 @@ import { ConfigurationPanelTableData } from 'components/Project/ProjectTabs/CyclesPayoutsTab/ConfigurationPanel' -import { useJBRulesetMetadata } from 'juice-sdk-react' +import { useJBRulesetByChain } from 'packages/v4/hooks/useJBRulesetByChain' import { useJBUpcomingRuleset } from 'packages/v4/hooks/useJBUpcomingRuleset' +import { useCyclesPanelSelectedChain } from '../contexts/CyclesPanelSelectedChainContext' import { useV4FormatConfigurationOtherRulesSection } from './useV4FormatConfigurationOtherRulesSection' export const useV4OtherRulesSection = ( type: 'current' | 'upcoming', ): ConfigurationPanelTableData => { - const { data: rulesetMetadata } = useJBRulesetMetadata() + const { selectedChainId } = useCyclesPanelSelectedChain() + + const { rulesetMetadata } = useJBRulesetByChain(selectedChainId) const { rulesetMetadata: upcomingRulesetMetadata, - } = useJBUpcomingRuleset() + } = useJBUpcomingRuleset(selectedChainId) return useV4FormatConfigurationOtherRulesSection({ rulesetMetadata, diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4PayoutsSubPanel.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4PayoutsSubPanel.tsx index b706b591ae..5d1699d1c7 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4PayoutsSubPanel.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4PayoutsSubPanel.tsx @@ -1,9 +1,10 @@ import { JBSplit, SPLITS_TOTAL_PERCENT } from 'juice-sdk-core' import { NativeTokenValue, useReadJbMultiTerminalFee } from 'juice-sdk-react' -import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' +import { useCallback, useMemo } from 'react' + +import useV4ProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' import { MAX_PAYOUT_LIMIT } from 'packages/v4/utils/math' import { v4GetProjectOwnerRemainderSplit } from 'packages/v4/utils/v4Splits' -import { useCallback, useMemo } from 'react' import assert from 'utils/assert' import { feeForAmount } from 'utils/math' import { useV4CurrentUpcomingPayoutLimit } from './useV4CurrentUpcomingPayoutLimit' @@ -30,7 +31,7 @@ const calculateSplitAmountWad = ( export const useV4PayoutsSubPanel = (type: 'current' | 'upcoming') => { const { splits, isLoading } = useV4CurrentUpcomingPayoutSplits(type) - const { data: projectOwnerAddress } = useProjectOwnerOf() + const { data: projectOwnerAddress } = useV4ProjectOwnerOf() const { data: primaryNativeTerminalFee } = useReadJbMultiTerminalFee() const { distributableAmount } = useV4DistributableAmount() diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4TokenSection.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4TokenSection.ts index baafc6cd8f..b55c2accc0 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4TokenSection.ts +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4TokenSection.ts @@ -1,6 +1,9 @@ +import { useJBTokenContext } from 'juice-sdk-react' + import { ConfigurationPanelTableData } from 'components/Project/ProjectTabs/CyclesPayoutsTab/ConfigurationPanel' -import { useJBRuleset, useJBRulesetMetadata, useJBTokenContext } from 'juice-sdk-react' +import { useJBRulesetByChain } from 'packages/v4/hooks/useJBRulesetByChain' import { useJBUpcomingRuleset } from 'packages/v4/hooks/useJBUpcomingRuleset' +import { useCyclesPanelSelectedChain } from '../contexts/CyclesPanelSelectedChainContext' import { useV4FormatConfigurationTokenSection } from './useV4FormatConfigurationTokenSection' export const useV4TokenSection = ( @@ -9,13 +12,15 @@ export const useV4TokenSection = ( const { token } = useJBTokenContext() const tokenSymbol = token?.data?.symbol - const { data: ruleset } = useJBRuleset() - const { data: rulesetMetadata } = useJBRulesetMetadata() + const { selectedChainId } = useCyclesPanelSelectedChain() + + const { ruleset, rulesetMetadata } = useJBRulesetByChain(selectedChainId) + const { ruleset: upcomingRuleset, rulesetMetadata: upcomingRulesetMetadata, isLoading: upcomingRulesetLoading - } = useJBUpcomingRuleset() + } = useJBUpcomingRuleset(selectedChainId) return useV4FormatConfigurationTokenSection({ ruleset, diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4TreasuryStats.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4TreasuryStats.tsx index ddb66d2d60..47bb8883f7 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4TreasuryStats.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4TreasuryStats.tsx @@ -1,5 +1,3 @@ -import { Tooltip } from 'antd' -import { NETWORKS } from 'constants/networks' import { JBChainId, NativeTokenValue, @@ -7,13 +5,14 @@ import { useSuckersNativeTokenBalance, useSuckersNativeTokenSurplus, } from 'juice-sdk-react' + +import { Tooltip } from 'antd' +import { NETWORKS } from 'constants/networks' import { ChainLogo } from 'packages/v4/components/ChainLogo' import { useMemo } from 'react' -import { useV4DistributableAmount } from './useV4DistributableAmount' export const useV4TreasuryStats = () => { const { data: rulesetMetadata } = useJBRulesetMetadata() - const { distributableAmount } = useV4DistributableAmount() const { data: suckersBalance } = useSuckersNativeTokenBalance() const totalBalance = @@ -33,6 +32,18 @@ export const useV4TreasuryStats = () => { return acc + curr.surplus }, 0n) ?? 0n + const distributableAmountByChain = suckersBalance?.map((chainBalanceObj) => { + const chainSurplus = ethSurplusByChain?.find((chainSurplus) => chainSurplus.chainId === chainBalanceObj.chainId)?.surplus ?? 0n + return { + chainId: chainBalanceObj.chainId, + projectId: chainBalanceObj.projectId, + distributableAmount: chainBalanceObj.balance - chainSurplus + } + }) + + const totalDistributableAmount = + distributableAmountByChain?.reduce((acc, curr) => acc + curr.distributableAmount, 0n) ?? 0n + const treasuryBalance = useMemo(() => { // NOTE: Don't think we need this since other chains payouts limits may be different? // if (payoutLimit && payoutLimit.amount === MAX_PAYOUT_LIMIT) @@ -115,7 +126,41 @@ export const useV4TreasuryStats = () => { ) }, [totalEthSurplus, ethSurplusByChain]) - const availableToPayout = + const availableToPayout = useMemo(() => { + return ( + 0 ? ( +
+ {distributableAmountByChain?.map((distributableAmountObj, index) => ( +
+
+ + {NETWORKS[distributableAmountObj.chainId].label} +
+ + + +
+ ))} +
+ ) : undefined + } + > + + + +
+ )}, [totalDistributableAmount, distributableAmountByChain] + ) return { treasuryBalance, diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx index 65dc9421e8..80827a5b69 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ProjectTabs.tsx @@ -1,12 +1,14 @@ +import { Fragment, useEffect, useMemo, useRef, useState } from 'react' + import { Tab } from '@headlessui/react' import { t } from '@lingui/macro' import { ProjectTab } from 'components/Project/ProjectTabs/ProjectTab' import { useOnScreen } from 'hooks/useOnScreen' -import { Fragment, useEffect, useMemo, useRef, useState } from 'react' import { twMerge } from 'tailwind-merge' import { useProjectPageQueries } from '../hooks/useProjectPageQueries' import V4AboutPanel from './V4AboutPanel' import { V4ActivityPanel } from './V4ActivityPanel/V4ActivityPanel' +import { CyclesPanelSelectedChainProvider } from './V4CyclesPayoutsPanel/contexts/CyclesPanelSelectedChainContext' import { V4CyclesPayoutsPanel } from './V4CyclesPayoutsPanel/V4CyclesPayoutsPanel' import { V4NftRewardsPanel } from './V4NftRewardsPanel/V4NftRewardsPanel' import { V4TokensPanel } from './V4TokensPanel/V4TokensPanel' @@ -57,9 +59,9 @@ export const V4ProjectTabs = ({ className }: { className?: string }) => { hideTab: !showNftRewards, }, { - id: 'cycle_payouts', + id: 'ruleset_payouts', name: t`Rulesets & Payouts`, - panel: , + panel: , }, { id: 'tokens', name: t`Tokens`, panel: }, ], diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4DistributeReservedTokensModal.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4DistributeReservedTokensModal.tsx index fd8c6a0f2c..10a67f3130 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4DistributeReservedTokensModal.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4DistributeReservedTokensModal.tsx @@ -1,13 +1,14 @@ -import { t, Trans } from '@lingui/macro' +import { Trans, t } from '@lingui/macro' +import { useJBContractContext, useJBTokenContext, useWriteJbControllerSendReservedTokensToSplitsOf } from 'juice-sdk-react' +import { useContext, useState } from 'react' + import { waitForTransactionReceipt } from '@wagmi/core' import TransactionModal from 'components/modals/TransactionModal' import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' -import { useJBContractContext, useJBTokenContext, useWriteJbControllerSendReservedTokensToSplitsOf } from 'juice-sdk-react' import SplitList from 'packages/v4/components/SplitList/SplitList' -import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' +import useV4ProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' import { useV4ReservedSplits } from 'packages/v4/hooks/useV4ReservedSplits' import { wagmiConfig } from 'packages/v4/wagmiConfig' -import { useContext, useState } from 'react' import { emitErrorNotification } from 'utils/notifications' import { tokenSymbolText } from 'utils/tokenSymbolText' import { useV4ReservedTokensSubPanel } from './hooks/useV4ReservedTokensSubPanel' @@ -25,7 +26,7 @@ export default function V4DistributeReservedTokensModal({ const { projectId, contracts } = useJBContractContext() const { splits: reservedTokensSplits } = useV4ReservedSplits() - const { data: projectOwnerAddress } = useProjectOwnerOf() + const { data: projectOwnerAddress } = useV4ProjectOwnerOf() const { token } = useJBTokenContext() const tokenSymbol = token?.data?.symbol diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4ReservedTokensSubPanel.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4ReservedTokensSubPanel.tsx index be5f9875a9..d050ccd063 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4ReservedTokensSubPanel.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4ReservedTokensSubPanel.tsx @@ -1,6 +1,8 @@ import { Trans, t } from '@lingui/macro' + import { TitleDescriptionDisplayCard } from 'components/Project/ProjectTabs/TitleDescriptionDisplayCard' import { reservedTokensTooltip } from 'components/Project/ProjectTabs/TokensPanelTooltips' +import { ProjectChainSelect } from 'packages/v4/components/ProjectDashboard/ProjectChainSelect' import { twMerge } from 'tailwind-merge' import { V4ProjectAllocationRow } from '../V4CyclesPayoutsPanel/V4ProjectAllocationRow' import { useV4ReservedTokensSubPanel } from './hooks/useV4ReservedTokensSubPanel' @@ -12,7 +14,8 @@ export const V4ReservedTokensSubPanel = ({ }: { className?: string }) => { - const { reservedList, pendingReservedTokensFormatted, reservedPercent } = + + const { selectedChainId, setSelectedChainId, reservedList, pendingReservedTokensFormatted, reservedPercent } = useV4ReservedTokensSubPanel() const reservedPercentTooltip = ( @@ -24,7 +27,15 @@ export const V4ReservedTokensSubPanel = ({ return (

+
Reserved tokens + { selectedChainId ? + setSelectedChainId(chainId)} + /> + : null } +

diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/hooks/useV4ReservedTokensSubPanel.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/hooks/useV4ReservedTokensSubPanel.ts index 63bfad69e2..e6f51c0b6d 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/hooks/useV4ReservedTokensSubPanel.ts +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/hooks/useV4ReservedTokensSubPanel.ts @@ -1,25 +1,36 @@ -import { formatEther, SplitPortion, SPLITS_TOTAL_PERCENT } from 'juice-sdk-core' +import { JBChainId, SPLITS_TOTAL_PERCENT, SplitPortion, formatEther } from 'juice-sdk-core' import { + useJBChainId, useJBContractContext, - useJBRulesetMetadata, - useReadJbControllerPendingReservedTokenBalanceOf, + useReadJbControllerPendingReservedTokenBalanceOf } from 'juice-sdk-react' -import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' +import { useEffect, useMemo, useState } from 'react' + +import { useJBRulesetByChain } from 'packages/v4/hooks/useJBRulesetByChain' +import { useProjectIdOfChain } from 'packages/v4/hooks/useProjectIdOfChain' +import useV4ProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' import { useV4ReservedSplits } from 'packages/v4/hooks/useV4ReservedSplits' -import { useMemo } from 'react' import assert from 'utils/assert' export const useV4ReservedTokensSubPanel = () => { - const { projectId, contracts } = useJBContractContext() - const { data: projectOwnerAddress } = useProjectOwnerOf() - const { splits: reservedTokensSplits } = useV4ReservedSplits() - const { data: rulesetMetadata } = useJBRulesetMetadata() + const { contracts } = useJBContractContext() + const projectPageChainId = useJBChainId() + + const [selectedChainId, setSelectedChainId] = useState() + + const projectId = useProjectIdOfChain({ chainId: selectedChainId }) + + const { data: projectOwnerAddress } = useV4ProjectOwnerOf(selectedChainId) + const { splits: reservedTokensSplits } = useV4ReservedSplits(selectedChainId) + + const { rulesetMetadata } = useJBRulesetByChain(selectedChainId) const reservedPercent = `${rulesetMetadata?.reservedPercent.formatPercentage()}%` const { data: pendingReservedTokens } = useReadJbControllerPendingReservedTokenBalanceOf({ address: contracts.controller.data ?? undefined, - args: [projectId], + args: [BigInt(projectId ?? 0)], + chainId: selectedChainId }) const reservedList = useMemo(() => { @@ -83,7 +94,13 @@ export const useV4ReservedTokensSubPanel = () => { return formatEther(pendingReservedTokens, { fractionDigits: 6 }) }, [pendingReservedTokens]) + useEffect(() => { + setSelectedChainId(projectPageChainId) + }, [projectPageChainId]) + return { + selectedChainId, + setSelectedChainId, reservedList, pendingReservedTokensFormatted: pendingReservedTokensFormatted, pendingReservedTokens: pendingReservedTokens, diff --git a/src/packages/v4/views/V4ProjectDashboard/hooks/useProjectPageQueries.ts b/src/packages/v4/views/V4ProjectDashboard/hooks/useProjectPageQueries.ts index 41ae2f2929..5cb57b0abb 100644 --- a/src/packages/v4/views/V4ProjectDashboard/hooks/useProjectPageQueries.ts +++ b/src/packages/v4/views/V4ProjectDashboard/hooks/useProjectPageQueries.ts @@ -1,12 +1,13 @@ +import { useCallback, useMemo } from 'react' + import { useRouter } from 'next/router' import { V4CurrencyOption } from 'packages/v4/models/v4CurrencyOption' -import { useCallback, useMemo } from 'react' type ProjectPageTab = | 'activity' | 'about' | 'nft_rewards' - | 'cycle_payouts' + | 'ruleset_payouts' | 'tokens' export type ProjectPayReceipt = { diff --git a/src/packages/v4/views/V4ProjectDashboard/hooks/useV4CurrentUpcomingSubPanel.ts b/src/packages/v4/views/V4ProjectDashboard/hooks/useV4CurrentUpcomingSubPanel.ts index 7561a68860..0a3ea75c2c 100644 --- a/src/packages/v4/views/V4ProjectDashboard/hooks/useV4CurrentUpcomingSubPanel.ts +++ b/src/packages/v4/views/V4ProjectDashboard/hooks/useV4CurrentUpcomingSubPanel.ts @@ -1,17 +1,21 @@ -import { t } from '@lingui/macro' import { - useJBRuleset, - useReadJbRulesetsCurrentApprovalStatusForLatestRulesetOf, + useReadJbRulesetsCurrentApprovalStatusForLatestRulesetOf } from 'juice-sdk-react' + +import { t } from '@lingui/macro' import { V4ApprovalStatus } from 'models/ballot' +import { useJBRulesetByChain } from 'packages/v4/hooks/useJBRulesetByChain' import { useJBUpcomingRuleset } from 'packages/v4/hooks/useJBUpcomingRuleset' import { useMemo } from 'react' import { timeSecondsToDateString } from 'utils/timeSecondsToDateString' +import { useCyclesPanelSelectedChain } from '../V4ProjectTabs/V4CyclesPayoutsPanel/contexts/CyclesPanelSelectedChainContext' export const useV4CurrentUpcomingSubPanel = (type: 'current' | 'upcoming') => { - const { data: ruleset, isLoading: rulesetLoading } = useJBRuleset() + const { selectedChainId } = useCyclesPanelSelectedChain() + + const { ruleset, isLoading: rulesetLoading } = useJBRulesetByChain(selectedChainId) const { ruleset: latestUpcomingRuleset, isLoading: upcomingRulesetsLoading } = - useJBUpcomingRuleset() + useJBUpcomingRuleset(selectedChainId) const { data: approvalStatus } = useReadJbRulesetsCurrentApprovalStatusForLatestRulesetOf() @@ -28,10 +32,10 @@ export const useV4CurrentUpcomingSubPanel = (type: 'current' | 'upcoming') => { const rulesetUnlocked = useMemo(() => { if (type === 'current') { - return ruleset?.duration === 0 ?? true + return Boolean(ruleset?.duration && ruleset?.duration === 0) ?? true } - return latestUpcomingRuleset?.duration == 0 ?? true - }, [ruleset?.duration, type, latestUpcomingRuleset?.duration]) + return Boolean(latestUpcomingRuleset && latestUpcomingRuleset.duration === 0) ?? true + }, [ruleset?.duration, type, latestUpcomingRuleset]) const upcomingRulesetLength = useMemo(() => { if (!latestUpcomingRuleset) @@ -45,7 +49,7 @@ export const useV4CurrentUpcomingSubPanel = (type: 'current' | 'upcoming') => { /** Determines if the CURRENT cycle is unlocked. * This is used to check if the upcoming cycle can start at any time. */ - const currentRulesetUnlocked = ruleset?.duration === 0 ?? true + const currentRulesetUnlocked = Boolean(ruleset && ruleset?.duration === 0) ?? true const status = rulesetUnlocked ? t`Unlocked` : t`Locked` diff --git a/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts b/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts index 6c7f8b3ef3..44a338c1d6 100644 --- a/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts +++ b/src/packages/v4/views/V4ProjectDashboard/hooks/useV4ProjectHeader.ts @@ -1,17 +1,18 @@ -import { useQuery } from '@tanstack/react-query' -import { BigNumber } from 'ethers' -import { useGnosisSafe } from 'hooks/safe/useGnosisSafe' -import { useProjectTrendingPercentageIncrease } from 'hooks/useProjectTrendingPercentageIncrease' import { SubtitleType, useSubtitle } from 'hooks/useSubtitle' import { useJBContractContext, useJBProjectMetadataContext, useSuckers, } from 'juice-sdk-react' + +import { useQuery } from '@tanstack/react-query' +import { BigNumber } from 'ethers' +import { useGnosisSafe } from 'hooks/safe/useGnosisSafe' +import { useProjectTrendingPercentageIncrease } from 'hooks/useProjectTrendingPercentageIncrease' import { GnosisSafe } from 'models/safe' import { ProjectsDocument } from 'packages/v4/graphql/client/graphql' import { useSubgraphQuery } from 'packages/v4/graphql/useSubgraphQuery' -import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' +import useV4ProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' import { fetchProjectsBySuckers } from 'packages/v4/utils/fetchProjectsBySuckers' import React from 'react' @@ -33,7 +34,7 @@ export const useV4ProjectHeader = (): ProjectHeaderData => { const { metadata } = useJBProjectMetadataContext() const projectMetadata = metadata?.data - const { data: projectOwnerAddress } = useProjectOwnerOf() + const { data: projectOwnerAddress } = useV4ProjectOwnerOf() const projectIdNum = parseInt(projectId.toString()) diff --git a/src/packages/v4/views/V4ProjectSettings/EditCyclePage/ReviewConfirmModal/DiffedSplits/DiffedSplitList.tsx b/src/packages/v4/views/V4ProjectSettings/EditCyclePage/ReviewConfirmModal/DiffedSplits/DiffedSplitList.tsx index dd18f15c57..0f8fc8b451 100644 --- a/src/packages/v4/views/V4ProjectSettings/EditCyclePage/ReviewConfirmModal/DiffedSplits/DiffedSplitList.tsx +++ b/src/packages/v4/views/V4ProjectSettings/EditCyclePage/ReviewConfirmModal/DiffedSplits/DiffedSplitList.tsx @@ -1,9 +1,9 @@ +import { processUniqueSplits, v4GetProjectOwnerRemainderSplit } from 'packages/v4/utils/v4Splits' + import { JBSplit as Split } from 'juice-sdk-core' import round from 'lodash/round' - import { SplitProps } from 'packages/v4/components/SplitList/SplitItem' -import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' -import { processUniqueSplits, v4GetProjectOwnerRemainderSplit } from 'packages/v4/utils/v4Splits' +import useV4ProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' import { useMemo } from 'react' import { DiffedSplitItem } from './DiffedSplitItem' @@ -37,7 +37,7 @@ export default function DiffedSplitList({ reservedPercent, showDiffs, }: DiffedSplitListProps) { - const { data: projectOwnerAddress } = useProjectOwnerOf() + const { data: projectOwnerAddress } = useV4ProjectOwnerOf() const ownerSplit = useMemo(() => { if (!projectOwnerAddress) return return v4GetProjectOwnerRemainderSplit(projectOwnerAddress, splits) diff --git a/src/packages/v4/views/V4ProjectSettings/EditCyclePage/hooks/useLoadEditCycleData.tsx b/src/packages/v4/views/V4ProjectSettings/EditCyclePage/hooks/useLoadEditCycleData.tsx index 2acd8b1cf1..753ce636d2 100644 --- a/src/packages/v4/views/V4ProjectSettings/EditCyclePage/hooks/useLoadEditCycleData.tsx +++ b/src/packages/v4/views/V4ProjectSettings/EditCyclePage/hooks/useLoadEditCycleData.tsx @@ -1,16 +1,16 @@ -import { Form } from 'antd' +import { useJBRuleset, useJBRulesetMetadata } from 'juice-sdk-react' import { useEffect, useState } from 'react' import { - deriveDurationOption, - deriveDurationUnit, - secondsToOtherUnit, + deriveDurationOption, + deriveDurationUnit, + secondsToOtherUnit, } from 'utils/format/formatTime' +import { Form } from 'antd' import { Ether } from 'juice-sdk-core' -import { useJBRuleset, useJBRulesetMetadata } from 'juice-sdk-react' import { useJBUpcomingRuleset } from 'packages/v4/hooks/useJBUpcomingRuleset' import { usePayoutLimit } from 'packages/v4/hooks/usePayoutLimit' -import { useV4CurrentPayoutSplits } from 'packages/v4/hooks/useV4PayoutSplits' +import { useV4CurrentPayoutSplits } from 'packages/v4/hooks/useV4CurrentPayoutSplits' import { useV4ReservedSplits } from 'packages/v4/hooks/useV4ReservedSplits' import { V4CurrencyName } from 'packages/v4/utils/currency' import { EditCycleFormFields } from '../EditCycleFormFields' diff --git a/src/packages/v4/views/V4ProjectSettings/EditNftsPage/EditNftsPage.tsx b/src/packages/v4/views/V4ProjectSettings/EditNftsPage/EditNftsPage.tsx index f4fac3115b..d84956b82b 100644 --- a/src/packages/v4/views/V4ProjectSettings/EditNftsPage/EditNftsPage.tsx +++ b/src/packages/v4/views/V4ProjectSettings/EditNftsPage/EditNftsPage.tsx @@ -2,7 +2,7 @@ import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' import { useJBRulesetContext } from 'juice-sdk-react' import { useNftDeployerCanReconfigure } from 'packages/v2v3/hooks/JB721Delegate/contractReader/useNftDeployerCanReconfigure' import { useHasNftRewards } from 'packages/v4/hooks/useHasNftRewards' -import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' +import useV4ProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' import { useContext } from 'react' import { LaunchNftsPage } from './LaunchNftCollection' import { EnableNftsCard } from './LaunchNftCollection/EnableNftsCard' @@ -11,7 +11,7 @@ import { UpdateNftsPage } from './UpdateNftsPage' export function EditNftsPage() { const { projectId } = useContext(ProjectMetadataContext) - const { data: projectOwnerAddress } = useProjectOwnerOf() + const { data: projectOwnerAddress } = useV4ProjectOwnerOf() const { rulesetMetadata: { data: _rulesetMetadata } } = useJBRulesetContext() const hasExistingNfts = useHasNftRewards() diff --git a/src/packages/v4/views/V4ProjectSettings/EditNftsPage/hooks/useUpdateCurrentCollection.ts b/src/packages/v4/views/V4ProjectSettings/EditNftsPage/hooks/useUpdateCurrentCollection.ts index 46667294cd..987910e2f7 100644 --- a/src/packages/v4/views/V4ProjectSettings/EditNftsPage/hooks/useUpdateCurrentCollection.ts +++ b/src/packages/v4/views/V4ProjectSettings/EditNftsPage/hooks/useUpdateCurrentCollection.ts @@ -1,16 +1,17 @@ -import { t } from '@lingui/macro' -import { waitForTransactionReceipt } from '@wagmi/core' -import { NEW_NFT_ID_LOWER_LIMIT } from 'components/NftRewards/RewardsList/AddEditRewardModal' -import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' import { useJBRulesetContext, useWriteJb721TiersHookAdjustTiers, } from 'juice-sdk-react' -import { JB721DelegateVersion } from 'models/JB721Delegate' import { JB_721_TIER_PARAMS_V4, NftRewardTier } from 'models/nftRewards' -import { wagmiConfig } from 'packages/v4/wagmiConfig' import { useCallback, useContext, useState } from 'react' import { buildJB721TierParams, pinNftRewards } from 'utils/nftRewards' + +import { t } from '@lingui/macro' +import { waitForTransactionReceipt } from '@wagmi/core' +import { NEW_NFT_ID_LOWER_LIMIT } from 'components/NftRewards/RewardsList/AddEditRewardModal' +import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' +import { JB721DelegateVersion } from 'models/JB721Delegate' +import { wagmiConfig } from 'packages/v4/wagmiConfig' import { emitErrorNotification } from 'utils/notifications' import { useChainId } from 'wagmi' @@ -87,6 +88,7 @@ export function useUpdateCurrentCollection({ rewardTiers, addTransaction, rulesetMetadata?.dataHook, + chainId, ]) return { diff --git a/src/packages/v4/views/V4ProjectSettings/ProjectSettingsDashboard.tsx b/src/packages/v4/views/V4ProjectSettings/ProjectSettingsDashboard.tsx index 548fcd903d..71698445ee 100644 --- a/src/packages/v4/views/V4ProjectSettings/ProjectSettingsDashboard.tsx +++ b/src/packages/v4/views/V4ProjectSettings/ProjectSettingsDashboard.tsx @@ -11,7 +11,7 @@ import Loading from 'components/Loading' import Link from 'next/link' import { useProjectHasErc20Token } from 'packages/v4/hooks/useProjectHasErc20Token' import { useV4BalanceOfNativeTerminal } from 'packages/v4/hooks/useV4BalanceOfNativeTerminal' -import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' +import useV4ProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf' import { useV4WalletHasPermission } from 'packages/v4/hooks/useV4WalletHasPermission' import { V4OperatorPermission } from 'packages/v4/models/v4Permissions' import { useV4DistributableAmount } from '../V4ProjectDashboard/V4ProjectTabs/V4CyclesPayoutsPanel/hooks/useV4DistributableAmount' @@ -57,7 +57,7 @@ function SettingsGroupCard({ } export function ProjectSettingsDashboard() { - const { data: projectOwnerAddress } = useProjectOwnerOf() + const { data: projectOwnerAddress } = useV4ProjectOwnerOf() const { data: balance, isLoading: loading } = useV4BalanceOfNativeTerminal() const { projectId } = useJBContractContext()