Skip to content

Commit

Permalink
feat: token tab chain select
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnyd-eth committed Jan 21, 2025
1 parent 27cab35 commit df948eb
Show file tree
Hide file tree
Showing 35 changed files with 420 additions and 179 deletions.
6 changes: 3 additions & 3 deletions src/locales/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -2819,6 +2819,9 @@ msgstr ""
msgid "Transfer unclaimed {0}"
msgstr ""

msgid "Ok"
msgstr ""

msgid "Cannot set payouts because your <0>Total payouts</0> is Zero."
msgstr ""

Expand Down Expand Up @@ -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 ""

Expand Down
5 changes: 3 additions & 2 deletions src/packages/v4/components/PayoutsTable/TotalRows.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Trans, t } from '@lingui/macro'

import { Tooltip } from 'antd'
import EthereumAddress from 'components/EthereumAddress'
import { PayoutsTableCell } from 'components/PayoutsTable/PayoutsTableCell'
import { PayoutsTableRow } from 'components/PayoutsTable/PayoutsTableRow'
import TooltipLabel from 'components/TooltipLabel'
import round from 'lodash/round'
import useProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf'
import useV4ProjectOwnerOf from 'packages/v4/hooks/useV4ProjectOwnerOf'
import { usePayoutsTable } from './hooks/usePayoutsTable'

const Row = PayoutsTableRow
Expand All @@ -31,7 +32,7 @@ export function TotalRows() {
? round(distributionLimit, roundingPrecision)
: t`Unlimited`

const { data: projectOwnerAddress } = useProjectOwnerOf()
const { data: projectOwnerAddress } = useV4ProjectOwnerOf()

const subTotalExceedsMax = distributionLimitIsInfinite && subTotal > 100

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const ProjectChainSelect: React.FC<

return (
<JuiceListbox
className="text-sm font-normal"
value={{
label: NETWORKS[value ?? DEFAULT_PROJECT_CHAIN_ID]?.label,
value,
Expand Down
37 changes: 37 additions & 0 deletions src/packages/v4/hooks/useJBAllRulesetsCrossChain.ts
Original file line number Diff line number Diff line change
@@ -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
}
}
46 changes: 46 additions & 0 deletions src/packages/v4/hooks/useJBRulesetByChain.ts
Original file line number Diff line number Diff line change
@@ -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,
}
}
8 changes: 3 additions & 5 deletions src/packages/v4/hooks/useJBUpcomingRuleset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,15 @@ export function useJBUpcomingRuleset(chainId?: JBChainId): {
rulesetMetadata: JBRulesetMetadata | undefined
isLoading: boolean
} {
const { contracts } = useJBContractContext()
const { contracts, projectId: defaultProjectId } = useJBContractContext()

const projectIdOfChain = useProjectIdOfChain({ chainId })
const projectId = useProjectIdOfChain({ chainId })

const { data, isLoading } = useReadJbControllerUpcomingRulesetOf({
address: contracts.controller?.data ?? undefined,
args: [BigInt(projectIdOfChain ?? 0)],
args: [BigInt(projectId ?? defaultProjectId)],
chainId
})

if (!projectIdOfChain) return { ruleset: undefined, rulesetMetadata: undefined, isLoading: false }

const _latestUpcomingRuleset = data?.[0]
const _latestUpcomingRulesetMetadata = data?.[1]
Expand Down
12 changes: 3 additions & 9 deletions src/packages/v4/hooks/useProjectIdOfChain.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import { JBChainId } from "juice-sdk-core";
import { useSuckers } from "juice-sdk-react";
import { useCurrentRouteChainId } from "./useCurrentRouteChainId";

// Gets the projectId of a project on a particular chain
// Gets the projectId of a project on a given chain
// -> (Project IDs can vary across chains)
//
// If project does not exist on given chain, returns undefined
export function useProjectIdOfChain({
chainId
}: {
chainId: JBChainId | undefined
}) {
const currentRouteChainId = useCurrentRouteChainId()
const _chainId = chainId ?? currentRouteChainId

}) {
const { data: suckers } = useSuckers()

return suckers?.find((suckerPair) => suckerPair.peerChainId === _chainId )?.peerChainId
return suckers?.find((suckerPair) => suckerPair.peerChainId === chainId )?.projectId
}
40 changes: 40 additions & 0 deletions src/packages/v4/hooks/useProjectRulesetsDiffAcrossChains.ts
Original file line number Diff line number Diff line change
@@ -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<JBChainId, JBRulesetData & JBRulesetMetadata>
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
// }
}
6 changes: 2 additions & 4 deletions src/packages/v4/hooks/useV4CurrentPayoutSplits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import {
import { useProjectIdOfChain } from './useProjectIdOfChain'

export const useV4CurrentPayoutSplits = (chainId?: JBChainId) => {
const projectIdOfChainId = useProjectIdOfChain({ chainId })
const projectId = useProjectIdOfChain({ chainId })

const { data: tokenAddress } = useReadJbTokensTokenOf()
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))`

const { data, isLoading } = useReadJbSplitsSplitsOf({
args: [BigInt(projectIdOfChainId ?? 0), rulesetId, groupId],
args: [BigInt(projectId ?? 0), rulesetId, groupId],
query: {
select(data) {
return data.map(
Expand All @@ -37,7 +37,5 @@ export const useV4CurrentPayoutSplits = (chainId?: JBChainId) => {

if (rulesetIsLoading) return { data: undefined, isLoading: true}

if (!projectIdOfChainId) return { data: undefined, isLoading: false}

return { data, isLoading }
}
12 changes: 7 additions & 5 deletions src/packages/v4/hooks/useV4ProjectOwnerOf.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -13,4 +15,4 @@ const useProjectOwnerOf = () => {
};
};

export default useProjectOwnerOf;
export default useV4ProjectOwnerOf;
15 changes: 8 additions & 7 deletions src/packages/v4/hooks/useV4ReservedSplits.ts
Original file line number Diff line number Diff line change
@@ -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 => ({
Expand All @@ -23,7 +24,7 @@ export const useV4ReservedSplits = () => {
},
},
})

const splits: JBSplit[] = _splits ? [..._splits] : []

return { splits, isLoading: currentSplitsLoading }
Expand Down
6 changes: 3 additions & 3 deletions src/packages/v4/hooks/useV4UpcomingPayoutSplits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useJBUpcomingRuleset } from './useJBUpcomingRuleset'
import { useProjectIdOfChain } from './useProjectIdOfChain'

export const useV4UpcomingPayoutSplits = (chainId?: JBChainId) => {
const projectIdOfChainId = useProjectIdOfChain({ chainId })
const projectId = useProjectIdOfChain({ chainId })

const { ruleset: upcomingRuleset, isLoading: upcomingRulesetLoading } =
useJBUpcomingRuleset(chainId)
Expand All @@ -22,7 +22,7 @@ export const useV4UpcomingPayoutSplits = (chainId?: JBChainId) => {

const { data, isLoading } = useReadJbSplitsSplitsOf({
args: [
BigInt(projectIdOfChainId ?? 0),
BigInt(projectId ?? 0),
BigInt(upcomingRuleset?.id ?? 0),
groupId,
],
Expand All @@ -41,7 +41,7 @@ export const useV4UpcomingPayoutSplits = (chainId?: JBChainId) => {
return { data: undefined, isLoading: true }
}

if (!projectIdOfChainId) return { data: undefined, isLoading: false}
if (!projectId) return { data: undefined, isLoading: false}


return { data, isLoading }
Expand Down
7 changes: 4 additions & 3 deletions src/packages/v4/hooks/useV4WalletHasPermission.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
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[],
): boolean {
const { userAddress } = useWallet()

const { projectId } = useJBContractContext()
const { data: projectOwnerAddress } = useProjectOwnerOf()
const { data: projectOwnerAddress } = useV4ProjectOwnerOf()

const _operator = userAddress ?? zeroAddress
const _account = projectOwnerAddress ?? zeroAddress
Expand Down
40 changes: 40 additions & 0 deletions src/packages/v4/utils/rulesetDiff.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { JBChainId, JBRulesetData, JBRulesetMetadata } from "juice-sdk-core";

export function getDiffedAttrBetweenRulesets(rulesetsByChain: Record<JBChainId, {
ruleset: JBRulesetData,
metadata: JBRulesetMetadata
}>) {
// 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<JBChainId, Partial<JBRulesetData & JBRulesetMetadata>>

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
}
Loading

0 comments on commit df948eb

Please sign in to comment.