From a3c9fa8377e4afc51236a1d12e0e8422d32b753c Mon Sep 17 00:00:00 2001 From: Johnny D Date: Mon, 9 Dec 2024 09:39:35 +1100 Subject: [PATCH 01/13] V4 nft forms currency symbol [2/n] (#4559) Co-authored-by: aeolian <94939382+aeolianeth@users.noreply.github.com> --- package.json | 4 +- .../AddNftCollectionForm.tsx | 8 ++- .../RewardsList/AddEditRewardModal.tsx | 11 ++-- .../NftRewards/RewardsList/RewardItem.tsx | 9 ++-- .../NftRewards/RewardsList/RewardsList.tsx | 6 ++- src/hooks/Wallet/hooks/useChainUnsupported.ts | 4 +- .../pages/NftRewards/NftRewardsPage.tsx | 6 ++- .../RewardsReview/RewardsReview.tsx | 4 ++ .../LaunchNftsCollection.tsx | 10 ++-- .../UpdateNftsPage/EditNftsSection.tsx | 19 ++++--- .../pages/NftRewards/NftRewardsPage.tsx | 7 ++- .../RewardsReview/RewardsReview.tsx | 5 ++ .../v4/contexts/V4SettingsProvider.tsx | 10 ++-- .../transactor/useLaunchProjectWithNftsTx.ts | 48 +++++++++-------- .../v4/hooks/useCurrentRouteChainId.ts | 3 -- src/packages/v4/hooks/useLaunchProjectTx.ts | 47 +++++++++------- src/packages/v4/hooks/useV4ProjectRoute.ts | 11 ---- .../V4ProjectDashboard/V4ProjectHeader.tsx | 19 +++---- .../V4TokensPanel/V4TokensPanel.tsx | 17 +++--- .../LaunchNftsCollection.tsx | 11 ++-- .../UpdateNftsPage/EditNftsSection.tsx | 14 +++-- .../hooks/useUpdateCurrentCollection.ts | 43 ++++++++------- .../ProjectSettingsLayout.tsx | 7 ++- .../hooks/useSettingsPagePath.ts | 7 ++- src/utils/nftRewards.ts | 53 ++++++++++--------- yarn.lock | 16 +++--- 26 files changed, 223 insertions(+), 176 deletions(-) delete mode 100644 src/packages/v4/hooks/useV4ProjectRoute.ts diff --git a/package.json b/package.json index a39af736a8..ffb3fdea64 100644 --- a/package.json +++ b/package.json @@ -106,8 +106,8 @@ "graphql": "^16.8.1", "he": "^1.2.0", "jsonwebtoken": "^9.0.0", - "juice-sdk-core": "^11.5.0-alpha", - "juice-sdk-react": "^11.6.0-alpha", + "juice-sdk-core": "^11.6.0-alpha", + "juice-sdk-react": "^11.7.1-alpha", "juicebox-metadata-helper": "0.1.7", "less": "4.1.2", "lodash": "^4.17.21", diff --git a/src/components/NftRewards/AddNftCollectionForm/AddNftCollectionForm.tsx b/src/components/NftRewards/AddNftCollectionForm/AddNftCollectionForm.tsx index fdd41bf0d0..f31acc9273 100644 --- a/src/components/NftRewards/AddNftCollectionForm/AddNftCollectionForm.tsx +++ b/src/components/NftRewards/AddNftCollectionForm/AddNftCollectionForm.tsx @@ -34,6 +34,7 @@ export const AddNftCollectionForm = ({ nftRewardsData, okButton, onFinish, + priceCurrencySymbol, }: { form: FormInstance initialValues?: NftRewardsFormProps @@ -41,6 +42,7 @@ export const AddNftCollectionForm = ({ nftRewardsData: NftRewardsData okButton: React.ReactNode onFinish?: VoidFunction + priceCurrencySymbol: string }) => { const lockPageRulesWrapper = useLockPageRulesWrapper() @@ -59,7 +61,11 @@ export const AddNftCollectionForm = ({ >
- + {hasNfts && ( diff --git a/src/components/NftRewards/RewardsList/AddEditRewardModal.tsx b/src/components/NftRewards/RewardsList/AddEditRewardModal.tsx index eb45425d6c..c2eb1c4b8f 100644 --- a/src/components/NftRewards/RewardsList/AddEditRewardModal.tsx +++ b/src/components/NftRewards/RewardsList/AddEditRewardModal.tsx @@ -1,5 +1,5 @@ import { QuestionCircleOutlined } from '@ant-design/icons' -import { t, Trans } from '@lingui/macro' +import { Trans, t } from '@lingui/macro' import { Form, Modal, Tooltip } from 'antd' import InputAccessoryButton from 'components/buttons/InputAccessoryButton' import { WarningCallout } from 'components/Callout/WarningCallout' @@ -17,7 +17,6 @@ import { NftRewardTier } from 'models/nftRewards' import { CreateCollapse } from 'packages/v2v3/components/Create/components/CreateCollapse/CreateCollapse' import { OptionalHeader } from 'packages/v2v3/components/Create/components/OptionalHeader' import { DEFAULT_NFT_MAX_SUPPLY } from 'packages/v2v3/constants/nftRewards' -import { V2V3_CURRENCY_USD } from 'packages/v2v3/utils/currency' import { UploadRequestOption } from 'rc-upload/lib/interface' import { useCallback, useEffect, useLayoutEffect, useState } from 'react' import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' @@ -56,6 +55,7 @@ export const NEW_NFT_ID_LOWER_LIMIT = 1000000 export const AddEditRewardModal = ({ className, + currencySymbol, editingData, nftRewards, open, @@ -64,6 +64,7 @@ export const AddEditRewardModal = ({ withEditWarning = false, }: { className?: string + currencySymbol: string editingData?: NftRewardTier | undefined nftRewards: NftRewardsData open?: boolean @@ -245,11 +246,7 @@ export const AddEditRewardModal = ({ rules={[inputMustExistRule({ label: t`Minimum Contribution` })]} > - } + accessory={} /> diff --git a/src/components/NftRewards/RewardsList/RewardItem.tsx b/src/components/NftRewards/RewardsList/RewardItem.tsx index 0e5a64be6c..17e32c31b2 100644 --- a/src/components/NftRewards/RewardsList/RewardItem.tsx +++ b/src/components/NftRewards/RewardsList/RewardItem.tsx @@ -6,7 +6,6 @@ import { JuiceVideoThumbnailOrImage } from 'components/JuiceVideo/JuiceVideoThum import TooltipLabel from 'components/TooltipLabel' import round from 'lodash/round' import { NftRewardTier } from 'models/nftRewards' -import { V2V3_CURRENCY_USD } from 'packages/v2v3/utils/currency' import { ReactNode } from 'react' import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' import { isZeroAddress } from 'utils/address' @@ -29,11 +28,13 @@ function numberUpToPrecisionFormat( export const RewardItem = ({ reward, nftRewards, + priceCurrencySymbol, onEditClicked, onDeleteClicked, }: { reward: NftRewardTier nftRewards: NftRewardsData + priceCurrencySymbol: string onEditClicked?: () => void onDeleteClicked?: () => void }) => { @@ -97,9 +98,9 @@ export const RewardItem = ({
{hasLimitedSupply(maxSupply) && ( >({ rewards: [], @@ -34,6 +34,7 @@ type RewardsListProps = FormItemInput & { allowCreate?: boolean withEditWarning?: boolean nftRewardsData: NftRewardsData + priceCurrencySymbol: string } interface RewardsListChildrenExports { @@ -44,6 +45,7 @@ interface RewardsListChildrenExports { export const RewardsList: React.FC> & RewardsListChildrenExports = ({ allowCreate = false, + priceCurrencySymbol, value, onChange, withEditWarning, @@ -82,6 +84,7 @@ export const RewardsList: React.FC> &
{ setSelectedReward(reward) @@ -112,6 +115,7 @@ export const RewardsList: React.FC> & )}
{ if (!connectedChain) { diff --git a/src/packages/v2v3/components/Create/components/pages/NftRewards/NftRewardsPage.tsx b/src/packages/v2v3/components/Create/components/pages/NftRewards/NftRewardsPage.tsx index 40aaf02b0b..ca917a589b 100644 --- a/src/packages/v2v3/components/Create/components/pages/NftRewards/NftRewardsPage.tsx +++ b/src/packages/v2v3/components/Create/components/pages/NftRewards/NftRewardsPage.tsx @@ -1,11 +1,12 @@ import { AddNftCollectionForm } from 'components/NftRewards/AddNftCollectionForm/AddNftCollectionForm' import { CREATE_FLOW } from 'constants/fathomEvents' import { trackFathomGoal } from 'lib/fathom' +import { V2V3_CURRENCY_USD } from 'packages/v2v3/utils/currency' import { useContext } from 'react' import { useAppSelector } from 'redux/hooks/useAppSelector' import { useSetCreateFurthestPageReached } from 'redux/hooks/useEditingCreateFurthestPageReached' -import { Wizard } from '../../Wizard/Wizard' import { PageContext } from '../../Wizard/contexts/PageContext' +import { Wizard } from '../../Wizard/Wizard' import { useCreateFlowNftRewardsForm } from './hooks/useCreateFlowNftRewardsForm' export function NftRewardsPage() { @@ -22,9 +23,12 @@ export function NftRewardsPage() { useSetCreateFurthestPageReached('nftRewards') + const nftCurrency = nftRewardsData?.pricing.currency + return ( { return formatEnabled(nftRewardsData.flags.preventOverspending) }, [nftRewardsData.flags.preventOverspending]) + const nftCurrency = nftRewardsData?.pricing.currency + return (
state.creatingV2Project.nftRewards, ) + const nftCurrency = nftRewardsData?.pricing.currency + return ( <> @@ -68,6 +72,7 @@ export function EditNftsSection() {
} + priceCurrencySymbol={NATIVE_TOKEN_SYMBOLS[chainId as JBChainId]} onFinish={() => { goToNextPage?.() trackFathomGoal(CREATE_FLOW.NFT_NEXT_CTA) diff --git a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx index fbfa22b23a..3d9b8604ac 100644 --- a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx +++ b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx @@ -1,5 +1,6 @@ import { t } from '@lingui/macro' import { RewardsList } from 'components/NftRewards/RewardsList/RewardsList' +import { JBChainId, NATIVE_TOKEN_SYMBOLS } from 'juice-sdk-core' import { NftRewardTier } from 'models/nftRewards' import { useCallback, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' @@ -7,6 +8,7 @@ import { useAppSelector } from 'redux/hooks/useAppSelector' import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { formatEnabled } from 'utils/format/formatBoolean' import { v4 } from 'uuid' +import { useChainId } from 'wagmi' import { ReviewDescription } from '../ReviewDescription' export const RewardsReview = () => { @@ -65,9 +67,12 @@ export const RewardsReview = () => { return formatEnabled(nftRewardsData.flags.preventOverspending) }, [nftRewardsData.flags.preventOverspending]) + const chainId = useChainId() + return (
= ({ children, }) => { const router = useRouter() + const chainId = useCurrentRouteChainId() - const { projectId: rawProjectId, chainName } = router.query + const { projectId: rawProjectId } = router.query if (!rawProjectId) return null const projectId = parseInt(rawProjectId as string) const projectIdBigInt = BigInt(projectId) - const chainId = chainNameMap[chainName as string] return ( @@ -38,9 +38,7 @@ export const V4SettingsProvider: React.FC = ({ - - {children} - + {children} diff --git a/src/packages/v4/hooks/JB721Delegate/transactor/useLaunchProjectWithNftsTx.ts b/src/packages/v4/hooks/JB721Delegate/transactor/useLaunchProjectWithNftsTx.ts index 9fd869a9a0..9558d5bbc6 100644 --- a/src/packages/v4/hooks/JB721Delegate/transactor/useLaunchProjectWithNftsTx.ts +++ b/src/packages/v4/hooks/JB721Delegate/transactor/useLaunchProjectWithNftsTx.ts @@ -1,18 +1,35 @@ +import { waitForTransactionReceipt } from '@wagmi/core' +import { JUICEBOX_MONEY_PROJECT_METADATA_DOMAIN } from 'constants/metadataDomain' +import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' +import { useWallet } from 'hooks/Wallet' import { DEFAULT_MEMO, NATIVE_TOKEN, NATIVE_TOKEN_DECIMALS, } from 'juice-sdk-core' import { + JBChainId, jbPricesAddress, useJBContractContext, - useWriteJb721TiersHookProjectDeployerLaunchProjectFor + useWriteJb721TiersHookProjectDeployerLaunchProjectFor, } from 'juice-sdk-react' +import { isValidMustStartAtOrAfter } from 'packages/v2v3/utils/fundingCycle' import { JBDeploy721TiersHookConfig, LaunchProjectWithNftsTxArgs, } from 'packages/v4/models/nfts' +import { wagmiConfig } from 'packages/v4/wagmiConfig' +import { useContext } from 'react' +import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/shared/v2ProjectDefaultState' +import { ipfsUri } from 'utils/ipfs' import { Address, WaitForTransactionReceiptReturnType, zeroAddress } from 'viem' +import { + arbitrumSepolia, + baseSepolia, + optimismSepolia, + sepolia, +} from 'viem/chains' +import { useChainId } from 'wagmi' import { LaunchV2V3ProjectArgs, transformV2V3CreateArgsToV4, @@ -23,17 +40,6 @@ import { SUPPORTED_JB_MULTITERMINAL_ADDRESS, } from '../../useLaunchProjectTx' -import { waitForTransactionReceipt } from '@wagmi/core' -import { JUICEBOX_MONEY_PROJECT_METADATA_DOMAIN } from 'constants/metadataDomain' -import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' -import { useWallet } from 'hooks/Wallet' -import { isValidMustStartAtOrAfter } from 'packages/v2v3/utils/fundingCycle' -import { wagmiConfig } from 'packages/v4/wagmiConfig' -import { useContext } from 'react' -import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/shared/v2ProjectDefaultState' -import { ipfsUri } from 'utils/ipfs' -import { useChainId } from 'wagmi' - /** * Return the project ID created from a `launchProjectFor` transaction. * @param txReceipt receipt of `launchProjectFor` transaction @@ -53,10 +59,10 @@ export const getProjectIdFromNftLaunchReceipt = ( * @todo not ideal to hardcode these addresses */ export const SUPPORTED_JB_721_TIER_STORE = { - '84532': '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, - '421614': '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, - '11155111': '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, - '11155420': '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, + [sepolia.id]: '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, + [optimismSepolia.id]: '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, + [arbitrumSepolia.id]: '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, + [baseSepolia.id]: '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, } export function useLaunchProjectWithNftsTx() { @@ -65,17 +71,15 @@ export function useLaunchProjectWithNftsTx() { const { userAddress } = useWallet() const chainId = useChainId() - const chainIdStr = - chainId?.toString() as keyof typeof SUPPORTED_JB_MULTITERMINAL_ADDRESS const defaultJBController = chainId - ? SUPPORTED_JB_CONTROLLER_ADDRESS[chainIdStr] + ? SUPPORTED_JB_CONTROLLER_ADDRESS[chainId as JBChainId] : undefined const defaultJBETHPaymentTerminal = chainId - ? SUPPORTED_JB_MULTITERMINAL_ADDRESS[chainIdStr] + ? SUPPORTED_JB_MULTITERMINAL_ADDRESS[chainId as JBChainId] : undefined const JBTiered721DelegateStoreAddress = chainId - ? SUPPORTED_JB_721_TIER_STORE[chainIdStr] + ? SUPPORTED_JB_721_TIER_STORE[chainId as JBChainId] : undefined const { writeContractAsync: writeLaunchProject } = @@ -146,7 +150,7 @@ export function useLaunchProjectWithNftsTx() { tiersConfig: { currency, decimals: NATIVE_TOKEN_DECIMALS, - prices: jbPricesAddress[chainIdStr], + prices: jbPricesAddress[chainId as JBChainId], tiers, }, reserveBeneficiary: zeroAddress, diff --git a/src/packages/v4/hooks/useCurrentRouteChainId.ts b/src/packages/v4/hooks/useCurrentRouteChainId.ts index d5766f5bf1..ce35621834 100644 --- a/src/packages/v4/hooks/useCurrentRouteChainId.ts +++ b/src/packages/v4/hooks/useCurrentRouteChainId.ts @@ -4,9 +4,6 @@ import { chainNameMap } from '../utils/networks' export function useCurrentRouteChainId() { const router = useRouter() const { chainName } = router.query - if (!chainName) { - return undefined - } return chainNameMap[chainName as string] } diff --git a/src/packages/v4/hooks/useLaunchProjectTx.ts b/src/packages/v4/hooks/useLaunchProjectTx.ts index ae49aa1ba6..0b360772fd 100644 --- a/src/packages/v4/hooks/useLaunchProjectTx.ts +++ b/src/packages/v4/hooks/useLaunchProjectTx.ts @@ -1,20 +1,28 @@ -import { useCallback, useContext } from 'react' -import { Address, WaitForTransactionReceiptReturnType } from 'viem' -import { - LaunchV2V3ProjectArgs, - transformV2V3CreateArgsToV4, -} from '../utils/launchProjectTransformers' - import { waitForTransactionReceipt } from '@wagmi/core' import { JUICEBOX_MONEY_PROJECT_METADATA_DOMAIN } from 'constants/metadataDomain' import { DEFAULT_MEMO } from 'constants/transactionDefaults' import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' import { useWallet } from 'hooks/Wallet' import { NATIVE_TOKEN } from 'juice-sdk-core' -import { useWriteJbControllerLaunchProjectFor } from 'juice-sdk-react' +import { + JBChainId, + useWriteJbControllerLaunchProjectFor, +} from 'juice-sdk-react' import { LaunchV2V3ProjectData } from 'packages/v2v3/hooks/transactor/useLaunchProjectTx' +import { useCallback, useContext } from 'react' import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/shared/v2ProjectDefaultState' +import { Address, WaitForTransactionReceiptReturnType } from 'viem' +import { + arbitrumSepolia, + baseSepolia, + optimismSepolia, + sepolia, +} from 'viem/chains' import { useChainId } from 'wagmi' +import { + LaunchV2V3ProjectArgs, + transformV2V3CreateArgsToV4, +} from '../utils/launchProjectTransformers' import { wagmiConfig } from '../wagmiConfig' const CREATE_EVENT_IDX = 2 @@ -47,17 +55,17 @@ export const getProjectIdFromLaunchReceipt = ( * @todo not ideal to hardcode these addresses */ export const SUPPORTED_JB_MULTITERMINAL_ADDRESS = { - '84532': '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, - '421614': '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, - '11155111': '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, - '11155420': '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, + [sepolia.id]: '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, + [optimismSepolia.id]: '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, + [arbitrumSepolia.id]: '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, + [baseSepolia.id]: '0x4DeF0AA5B9CA095d11705284221b2878731ab4EF' as Address, } export const SUPPORTED_JB_CONTROLLER_ADDRESS = { - '84532': '0x219A5cE6d1c512D5b050ad2E3d380b8746BE0Cb8' as Address, - '421614': '0x219A5cE6d1c512D5b050ad2E3d380b8746BE0Cb8' as Address, - '11155111': '0x219A5cE6d1c512D5b050ad2E3d380b8746BE0Cb8' as Address, - '11155420': '0x219A5cE6d1c512D5b050ad2E3d380b8746BE0Cb8' as Address, + [sepolia.id]: '0x219A5cE6d1c512D5b050ad2E3d380b8746BE0Cb8' as Address, + [optimismSepolia.id]: '0x219A5cE6d1c512D5b050ad2E3d380b8746BE0Cb8' as Address, + [arbitrumSepolia.id]: '0x219A5cE6d1c512D5b050ad2E3d380b8746BE0Cb8' as Address, + [baseSepolia.id]: '0x219A5cE6d1c512D5b050ad2E3d380b8746BE0Cb8' as Address, } /** @@ -69,14 +77,13 @@ export function useLaunchProjectTx() { useWriteJbControllerLaunchProjectFor() const chainId = useChainId() - const chainIdStr = - chainId?.toString() as keyof typeof SUPPORTED_JB_MULTITERMINAL_ADDRESS + const terminalAddress = chainId - ? SUPPORTED_JB_MULTITERMINAL_ADDRESS[chainIdStr] + ? SUPPORTED_JB_MULTITERMINAL_ADDRESS[chainId as JBChainId] : undefined const controllerAddress = chainId - ? SUPPORTED_JB_CONTROLLER_ADDRESS[chainIdStr] + ? SUPPORTED_JB_CONTROLLER_ADDRESS[chainId as JBChainId] : undefined const { addTransaction } = useContext(TxHistoryContext) diff --git a/src/packages/v4/hooks/useV4ProjectRoute.ts b/src/packages/v4/hooks/useV4ProjectRoute.ts deleted file mode 100644 index 1e032acb8b..0000000000 --- a/src/packages/v4/hooks/useV4ProjectRoute.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { useChainId } from 'wagmi' -import { v4ProjectRoute } from '../utils/routes' - -export function useV4ProjectRoute(projectId: number) { - const chainId = useChainId() - - return v4ProjectRoute({ - chainId, - projectId, - }) -} diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx index decdad49b9..ce91676e82 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectHeader.tsx @@ -10,6 +10,7 @@ import { SocialLinkButton } from 'components/Project/ProjectHeader/SocialLinkBut // import { Subtitle } from 'components/Project/ProjectHeader/Subtitle' import { TruncatedText } from 'components/TruncatedText' import useMobile from 'hooks/useMobile' +import { useJBChainId } from 'juice-sdk-react' import Link from 'next/link' import { ProjectHeaderPopupMenu } from 'packages/v4/components/ProjectDashboard/components/ProjectHeaderPopupMenu' import V4ProjectHandleLink from 'packages/v4/components/V4ProjectHandleLink' @@ -17,7 +18,6 @@ import { useV4WalletHasPermission } from 'packages/v4/hooks/useV4WalletHasPermis import { V4OperatorPermission } from 'packages/v4/models/v4Permissions' import { settingsPagePath, v4ProjectRoute } from 'packages/v4/utils/routes' import { twMerge } from 'tailwind-merge' -import { useChainId } from 'wagmi' import { useV4ProjectHeader } from './hooks/useV4ProjectHeader' import { ProjectHeaderStats } from './ProjectHeaderStats' @@ -25,7 +25,7 @@ export type SocialLink = 'twitter' | 'discord' | 'telegram' | 'website' export const V4ProjectHeader = ({ className }: { className?: string }) => { const socialLinks = useSocialLinks() - const chainId = useChainId() + const chainId = useJBChainId() const { title, @@ -103,13 +103,14 @@ export const V4ProjectHeader = ({ className }: { className?: string }) => {
- {subtitle && - (subtitle.type === 'tagline' ? ( - - ) : null) + { + subtitle && + (subtitle.type === 'tagline' ? ( + + ) : null) // }
diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4TokensPanel.tsx b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4TokensPanel.tsx index 852df78c49..c70722c44a 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4TokensPanel.tsx +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4TokensPanel/V4TokensPanel.tsx @@ -11,13 +11,12 @@ import { SettingOutlined } from '@ant-design/icons' import { Button, Tooltip } from 'antd' import { AddTokenToMetamaskButton } from 'components/buttons/AddTokenToMetamaskButton' import { ISSUE_ERC20_EXPLANATION } from 'components/strings' -import { useJBContractContext } from 'juice-sdk-react' +import { useJBChainId, useJBContractContext } from 'juice-sdk-react' import { V4TokenHoldersModal } from 'packages/v4/components/modals/V4TokenHoldersModal/V4TokenHoldersModal' import { useProjectHasErc20Token } from 'packages/v4/hooks/useProjectHasErc20Token' import { v4ProjectRoute } from 'packages/v4/utils/routes' import { useCallback, useState } from 'react' import { reloadWindow } from 'utils/windowUtils' -import { useChainId } from 'wagmi' import { useV4BalanceMenuItemsUserFlags } from './hooks/useV4BalanceMenuItemsUserFlags' import { useV4TokensPanel } from './hooks/useV4TokensPanel' import { useV4YourBalanceMenuItems } from './hooks/useV4YourBalanceMenuItems' @@ -181,7 +180,7 @@ export const V4TokensPanel = () => { } const ProjectTokenCard = () => { - const chainId = useChainId() + const chainId = useJBChainId() const { projectId: projectIdBig } = useJBContractContext() const projectId = Number(projectIdBig) @@ -215,10 +214,14 @@ const ProjectTokenCard = () => { {canCreateErc20Token ? ( + )} + ) : ( No activity yet. )} @@ -226,3 +285,30 @@ function translateEventDataToPresenter( } } } + +type ProjectEventFilter = 'all' | EventType + +const ACTIVITY_OPTIONS = [ + { label: 'All activity', value: 'all' }, + { label: 'Paid', value: 'payEvent' }, + { label: 'Added to balance', value: 'addToBalanceEvent' }, + { label: 'Minted tokens', value: 'mintTokensEvent' }, + { label: 'Cashed out', value: 'cashOutEvent' }, + { label: 'Deployed ERC20', value: 'deployedERC20Event' }, + { label: 'Project created', value: 'projectCreateEvent' }, + { label: 'Distributed payouts', value: 'distributePayoutsEvent' }, + { + label: 'Distributed reserved tokens', + value: 'distributeReservedTokensEvent', + }, + { + label: 'Distributed to reserved token split', + value: 'distributeToReservedTokenSplitEvent', + }, + { + label: 'Distributed to payout split', + value: 'distributeToPayoutSplitEvent', + }, + { label: 'Used allowance', value: 'useAllowanceEvent' }, + { label: 'Burned', value: 'burnEvent' }, +] diff --git a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/utils/transformEventsData.ts b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/utils/transformEventsData.ts index 54a05b0235..bc8af6dadc 100644 --- a/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/utils/transformEventsData.ts +++ b/src/packages/v4/views/V4ProjectDashboard/V4ProjectTabs/V4ActivityPanel/utils/transformEventsData.ts @@ -1,7 +1,7 @@ import { Ether, JBProjectToken } from 'juice-sdk-core' import { ProjectEventsQuery } from 'packages/v4/graphql/client/graphql' -type EventType = +export type EventType = | 'payEvent' | 'addToBalanceEvent' | 'mintTokensEvent' From f6bf4ab250511b6a7e3ec8b2a78f6a622a9615d7 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Sun, 29 Dec 2024 10:14:46 +1000 Subject: [PATCH 08/13] Bump sdk --- package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index a8739be052..cc2f6741df 100644 --- a/package.json +++ b/package.json @@ -106,8 +106,8 @@ "graphql": "^16.8.1", "he": "^1.2.0", "jsonwebtoken": "^9.0.0", - "juice-sdk-core": "^12.1.0-alpha", - "juice-sdk-react": "^12.1.0-alpha", + "juice-sdk-core": "^12.2.2-alpha", + "juice-sdk-react": "^12.2.2-alpha", "juicebox-metadata-helper": "0.1.7", "less": "4.1.2", "lodash": "^4.17.21", diff --git a/yarn.lock b/yarn.lock index c428d2eddd..e12c374787 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12178,18 +12178,18 @@ jsx-ast-utils@^3.3.5: object.assign "^4.1.4" object.values "^1.1.6" -juice-sdk-core@^12.1.0-alpha: - version "12.1.0-alpha" - resolved "https://registry.yarnpkg.com/juice-sdk-core/-/juice-sdk-core-12.1.0-alpha.tgz#016aefb05ac9c7aa395d91240746c250f366283c" - integrity sha512-uVe+sdZgA8/pudUGh4duGfduwguVqBW6ez01WcstSgq9mEtWOnoP4T9KVAxyp92xlhFO9MLoj3a0GJzRg0K+zg== +juice-sdk-core@^12.2.2-alpha: + version "12.2.2-alpha" + resolved "https://registry.yarnpkg.com/juice-sdk-core/-/juice-sdk-core-12.2.2-alpha.tgz#74b29238e0d999a7d3b8f49748476e08a5f47c27" + integrity sha512-sLEniuN0bR1/bM3WVtcp1Xx8mqYLBwO1IeY/BSdmAlBUA1tT0BlQ0kvJ2G72i0ZefP6MlLXrWZVl+koPXeXnLA== dependencies: bs58 "^5.0.0" fpnum "^1.0.0" -juice-sdk-react@^12.1.0-alpha: - version "12.1.0-alpha" - resolved "https://registry.yarnpkg.com/juice-sdk-react/-/juice-sdk-react-12.1.0-alpha.tgz#97630084c2deff402598e808a8ffe1acf45fd744" - integrity sha512-961BNlHuwJfeqbh08nUIxkhxDcNYOGaZmaiOwWm1vpFUW4MNTlv81qtuH1H+QUPUDPg8OQw/bfqXRADGFz/WJA== +juice-sdk-react@^12.2.2-alpha: + version "12.2.2-alpha" + resolved "https://registry.yarnpkg.com/juice-sdk-react/-/juice-sdk-react-12.2.2-alpha.tgz#1ea4a85d474435cbb4314173a51231772b1df5ee" + integrity sha512-vwo3PITeIVFt70+vF+8Rjitt+MtJqdUdtlKNrxY6cwl5Fp3SyVnc0TclM1SwqcSedlJgU1lRtZSHkQ2mYv1YHA== juice@^10.0.0: version "10.0.0" From 0ec5223b5190a81e4264c6b9d362f9c7b3c5a1ec Mon Sep 17 00:00:00 2001 From: johnnyd-eth Date: Mon, 30 Dec 2024 12:59:54 +1000 Subject: [PATCH 09/13] fix: redemption modal fidelity, MAX button, ETHFromRedemption when 0 redemp rate --- .../V2V3BurnOrRedeemModal.tsx | 36 +++++++++++-------- .../useETHReceivedFromTokens.ts | 14 +++++--- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ManageTokensSection/AccountBalanceDescription/V2V3BurnOrRedeemModal.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ManageTokensSection/AccountBalanceDescription/V2V3BurnOrRedeemModal.tsx index ba1eb9ca72..3e39d27848 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ManageTokensSection/AccountBalanceDescription/V2V3BurnOrRedeemModal.tsx +++ b/src/packages/v2v3/components/V2V3Project/V2V3ManageTokensSection/AccountBalanceDescription/V2V3BurnOrRedeemModal.tsx @@ -1,26 +1,27 @@ -import { t, Trans } from '@lingui/macro' import { Checkbox, Descriptions, Form } from 'antd' +import { Trans, t } from '@lingui/macro' +import { fromWad, parseWad } from 'utils/format/formatNumber' +import { useContext, useState } from 'react' import { useForm, useWatch } from 'antd/lib/form/Form' -import InputAccessoryButton from 'components/buttons/InputAccessoryButton' + +import { BigNumber } from 'ethers' import { Callout } from 'components/Callout/Callout' import ETHAmount from 'components/currency/ETHAmount' import FormattedNumberInput from 'components/inputs/FormattedNumberInput' -import TransactionModal from 'components/modals/TransactionModal' -import { TokenAmount } from 'components/TokenAmount' +import InputAccessoryButton from 'components/buttons/InputAccessoryButton' import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' -import { BigNumber } from 'ethers' -import { useWallet } from 'hooks/Wallet' +import { TokenAmount } from 'components/TokenAmount' +import TransactionModal from 'components/modals/TransactionModal' import { V2V3ProjectContext } from 'packages/v2v3/contexts/Project/V2V3ProjectContext' -import { useETHReceivedFromTokens } from 'packages/v2v3/hooks/contractReader/useETHReceivedFromTokens' -import useTotalBalanceOf from 'packages/v2v3/hooks/contractReader/useTotalBalanceOf' -import { useBurnTokensTx } from 'packages/v2v3/hooks/transactor/useBurnTokensTx' -import { useRedeemTokensTx } from 'packages/v2v3/hooks/transactor/useRedeemTokensTx' import { V2V3_CURRENCY_USD } from 'packages/v2v3/utils/currency' -import { formatRedemptionRate } from 'packages/v2v3/utils/math' -import { useContext, useState } from 'react' -import { fromWad, parseWad } from 'utils/format/formatNumber' import { emitErrorNotification } from 'utils/notifications' +import { formatRedemptionRate } from 'packages/v2v3/utils/math' import { tokenSymbolText } from 'utils/tokenSymbolText' +import { useBurnTokensTx } from 'packages/v2v3/hooks/transactor/useBurnTokensTx' +import { useETHReceivedFromTokens } from 'packages/v2v3/hooks/contractReader/useETHReceivedFromTokens' +import { useRedeemTokensTx } from 'packages/v2v3/hooks/transactor/useRedeemTokensTx' +import useTotalBalanceOf from 'packages/v2v3/hooks/contractReader/useTotalBalanceOf' +import { useWallet } from 'hooks/Wallet' // This doubles as the 'Redeem' and 'Burn' modal depending on if project has overflow export function V2V3BurnOrRedeemModal({ @@ -187,7 +188,7 @@ export function V2V3BurnOrRedeemModal({ const personalBalanceExceeded = redeemAmount && parseFloat(redeemAmount) > parseFloat(fromWad(totalBalance)) const inUSD = distributionLimitCurrency?.eq(V2V3_CURRENCY_USD) - + return ( Total redemption value}> @@ -294,7 +296,11 @@ export function V2V3BurnOrRedeemModal({ accessory={ setRedeemAmount(fromWad(totalBalance))} + onClick={() => { + const maxRedeemAmount = fromWad(totalBalance) + setRedeemAmount(maxRedeemAmount) + form.setFieldsValue({ redeemAmount: maxRedeemAmount }) + }} /> } disabled={totalBalance?.eq(0)} diff --git a/src/packages/v2v3/hooks/contractReader/useETHReceivedFromTokens.ts b/src/packages/v2v3/hooks/contractReader/useETHReceivedFromTokens.ts index aa37c8e40e..3d8b5cfb00 100644 --- a/src/packages/v2v3/hooks/contractReader/useETHReceivedFromTokens.ts +++ b/src/packages/v2v3/hooks/contractReader/useETHReceivedFromTokens.ts @@ -1,10 +1,10 @@ -import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' import { BigNumber } from 'ethers' +import { MAX_REDEMPTION_RATE } from 'packages/v2v3/utils/math' +import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext' import { V2BallotState } from 'models/ballot' import { V2V3ProjectContext } from 'packages/v2v3/contexts/Project/V2V3ProjectContext' -import { MAX_REDEMPTION_RATE } from 'packages/v2v3/utils/math' -import { useContext } from 'react' import { parseWad } from 'utils/format/formatNumber' +import { useContext } from 'react' import { useProjectReservedTokens } from './ProjectReservedTokens' /** @@ -52,11 +52,15 @@ export function useETHReceivedFromTokens({ if (!fundingCycleMetadata || !realTotalTokenSupply?.gt(0) || !tokenAmount) return BigNumber.from(0) - const redemptionRate = + const redemptionRate = ballotState === V2BallotState.Active ? fundingCycleMetadata.ballotRedemptionRate : fundingCycleMetadata.redemptionRate + if (redemptionRate.eq(0)) { + return BigNumber.from(0) + } + const tokenAmountWad = parseWad(tokenAmount) // base = ox/s @@ -66,7 +70,7 @@ export function useETHReceivedFromTokens({ .mul(tokenAmountWad) .div(realTotalTokenSupply) : BigNumber.from(0) - + // numerator = r + (x(1 - r)/s) const numerator = redemptionRate.add( tokenAmountWad From 349bff8c436631accd90ff32d94b84e0815f56af Mon Sep 17 00:00:00 2001 From: johnnyd-eth Date: Mon, 30 Dec 2024 13:14:45 +1000 Subject: [PATCH 10/13] fix: ts compiler --- src/packages/v4/hooks/useETHReceivedFromTokens.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/packages/v4/hooks/useETHReceivedFromTokens.ts b/src/packages/v4/hooks/useETHReceivedFromTokens.ts index 48b13bd58b..28328d955b 100644 --- a/src/packages/v4/hooks/useETHReceivedFromTokens.ts +++ b/src/packages/v4/hooks/useETHReceivedFromTokens.ts @@ -1,4 +1,3 @@ -import { getTokenCashOutQuoteEth } from 'juice-sdk-core' import { useJBContractContext, useJBRulesetContext, @@ -7,6 +6,8 @@ import { useReadJbTokensTotalSupplyOf, } from 'juice-sdk-react' +import { getTokenCashOutQuoteEth } from 'juice-sdk-core' + export function useETHReceivedFromTokens( tokenAmountWei: bigint | undefined, ): bigint | undefined { @@ -35,12 +36,14 @@ export function useETHReceivedFromTokens( } try { - return getTokenCashOutQuoteEth(tokenAmountWei, { + const eth = getTokenCashOutQuoteEth(tokenAmountWei, { cashOutTaxRate: Number(cashOutTaxRate), totalSupply, tokensReserved, overflowWei: nativeTokenSurplus, }) + // v4TODO: make SDK return 0n, not 0 + return eth === 0 ? 0n : eth } catch (e) { // Division by zero can cause a RangeError if (e instanceof RangeError) { From 4dec75c64703c575d710bf28d4d072a672fe7179 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:43:26 +1000 Subject: [PATCH 11/13] sdk bump --- package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index cc2f6741df..05605b398b 100644 --- a/package.json +++ b/package.json @@ -106,8 +106,8 @@ "graphql": "^16.8.1", "he": "^1.2.0", "jsonwebtoken": "^9.0.0", - "juice-sdk-core": "^12.2.2-alpha", - "juice-sdk-react": "^12.2.2-alpha", + "juice-sdk-core": "^12.2.4-alpha", + "juice-sdk-react": "^12.2.4-alpha", "juicebox-metadata-helper": "0.1.7", "less": "4.1.2", "lodash": "^4.17.21", diff --git a/yarn.lock b/yarn.lock index e12c374787..c612fd90bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12178,18 +12178,18 @@ jsx-ast-utils@^3.3.5: object.assign "^4.1.4" object.values "^1.1.6" -juice-sdk-core@^12.2.2-alpha: - version "12.2.2-alpha" - resolved "https://registry.yarnpkg.com/juice-sdk-core/-/juice-sdk-core-12.2.2-alpha.tgz#74b29238e0d999a7d3b8f49748476e08a5f47c27" - integrity sha512-sLEniuN0bR1/bM3WVtcp1Xx8mqYLBwO1IeY/BSdmAlBUA1tT0BlQ0kvJ2G72i0ZefP6MlLXrWZVl+koPXeXnLA== +juice-sdk-core@^12.2.4-alpha: + version "12.2.4-alpha" + resolved "https://registry.yarnpkg.com/juice-sdk-core/-/juice-sdk-core-12.2.4-alpha.tgz#b6c2d03b25a9c5660cdb82a83cb5a0d994f3a313" + integrity sha512-LvcjZCD3rNPrYXKQlG/WRaOA05yA+pjJFMROKWNk2vIBK/tdEglaeagwo1OXpW5JqjaoQ3RS83nT+aC8YvQSVA== dependencies: bs58 "^5.0.0" fpnum "^1.0.0" -juice-sdk-react@^12.2.2-alpha: - version "12.2.2-alpha" - resolved "https://registry.yarnpkg.com/juice-sdk-react/-/juice-sdk-react-12.2.2-alpha.tgz#1ea4a85d474435cbb4314173a51231772b1df5ee" - integrity sha512-vwo3PITeIVFt70+vF+8Rjitt+MtJqdUdtlKNrxY6cwl5Fp3SyVnc0TclM1SwqcSedlJgU1lRtZSHkQ2mYv1YHA== +juice-sdk-react@^12.2.4-alpha: + version "12.2.4-alpha" + resolved "https://registry.yarnpkg.com/juice-sdk-react/-/juice-sdk-react-12.2.4-alpha.tgz#2d53d1296d7d0817c3a7dda75b99570df12661f2" + integrity sha512-SX/WvlCANpgS568Ohdf7q+yC2jLY4vTUUGjgmZD2XUgCZTbfPorgUbZ4pxWwWgtfxydq6vyoPHcUUjWItMEPWw== juice@^10.0.0: version "10.0.0" From d3a95d4100fce2876607adf5be5f3fff2537c19f Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:57:04 +1000 Subject: [PATCH 12/13] edit logs --- .../ContractReader/useContractReadValue.ts | 12 +++++------- .../ContractReader/util/useCallContractRead.ts | 17 +++++++---------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/hooks/ContractReader/useContractReadValue.ts b/src/hooks/ContractReader/useContractReadValue.ts index 5b8e7ac771..fad02767ef 100644 --- a/src/hooks/ContractReader/useContractReadValue.ts +++ b/src/hooks/ContractReader/useContractReadValue.ts @@ -57,13 +57,11 @@ export function useContractReadValue({ const newValue = _formatter(result) if (_valueDidChange(value, newValue)) { - console.info( - `📗 New >`, - functionName, - { args }, - { newValue }, - { contract: readContract?.address }, - ) + console.info(`📗 New >`, functionName, { + args, + newValue, + contract: readContract?.address, + }) setValue(newValue) } } catch (err) { diff --git a/src/hooks/ContractReader/util/useCallContractRead.ts b/src/hooks/ContractReader/util/useCallContractRead.ts index 064f8a4d3d..a235b411aa 100644 --- a/src/hooks/ContractReader/util/useCallContractRead.ts +++ b/src/hooks/ContractReader/util/useCallContractRead.ts @@ -19,16 +19,13 @@ export async function callContractRead({ try { console.info(`📚 Read >`, functionName) return await readContract[functionName](...(args ?? [])) - } catch (err) { - console.error( - `📕 Read error >`, - functionName, - { args }, - { err }, - { contract: readContract.address }, - { contracts }, - ) + } catch (error) { + console.error(`📕 Read error >`, functionName, error, { + args, + contract: readContract.address, + contracts, + }) - throw err + throw error } } From 1e9ba29672e97d4458eff14152be7c68c1ff6159 Mon Sep 17 00:00:00 2001 From: aeolian <94939382+aeolianeth@users.noreply.github.com> Date: Mon, 30 Dec 2024 22:03:02 +1000 Subject: [PATCH 13/13] [PREVIEW]