Skip to content

Commit

Permalink
Merge pull request #1387 from DA0-DA0/development
Browse files Browse the repository at this point in the history
Deploy NFT fix
  • Loading branch information
NoahSaso authored Sep 22, 2023
2 parents 943528e + 9ac3b34 commit be0a0c9
Show file tree
Hide file tree
Showing 12 changed files with 440 additions and 279 deletions.
1 change: 1 addition & 0 deletions packages/stateful/actions/core/nfts/MintNft/MintNft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const MintNft: ActionComponent = (props) => {
creatingCollectionInfoLoading.loading
? undefined
: {
key: chainId + collectionAddress + mintMsg.token_id,
collection: {
address: collectionAddress,
name: creatingCollectionInfoLoading.data?.name ?? '',
Expand Down
32 changes: 17 additions & 15 deletions packages/stateful/components/NftCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
NftCard as StatelessNftCard,
useCachedLoadingWithError,
} from '@dao-dao/stateless'
import { WithChainId } from '@dao-dao/types'
import { LazyNftCardProps } from '@dao-dao/types'

import {
nftCardInfoSelector,
Expand All @@ -27,14 +27,9 @@ export const StakedNftCard = (props: ComponentProps<typeof NftCard>) => {
return <NftCard hideCollection ownerLabel={t('title.staker')} {...props} />
}

export type LazyNftCardProps = WithChainId<{
collectionAddress: string
tokenId: string
// If passed and the NFT is staked, get staker info from this contract.
stakingContractAddress?: string
}>

export const LazyNftCard = ({
key,
type = 'owner',
collectionAddress,
tokenId,
stakingContractAddress,
Expand All @@ -49,23 +44,30 @@ export const LazyNftCard = ({
)

const stakerOrOwner = useCachedLoadingWithError(
nftStakerOrOwnerSelector({
collectionAddress,
tokenId,
stakingContractAddress,
chainId,
})
type === 'owner'
? nftStakerOrOwnerSelector({
collectionAddress,
tokenId,
stakingContractAddress,
chainId,
})
: undefined
)

const staked =
!stakerOrOwner.loading &&
!stakerOrOwner.errored &&
stakerOrOwner.data.staked

const NftCardToUse = staked ? StakedNftCard : NftCardNoCollection
const NftCardToUse = staked
? StakedNftCard
: type === 'owner'
? NftCardNoCollection
: NftCard

return info.loading || info.errored ? (
<NftCardToUse
key={key}
chainId={chainId}
className="animate-pulse"
collection={{
Expand Down
12 changes: 6 additions & 6 deletions packages/stateful/components/dao/tabs/TreasuryAndNftsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import {
useDaoInfoContext,
useDaoNavHelpers,
} from '@dao-dao/stateless'
import { ActionKey, TokenCardInfo } from '@dao-dao/types'
import { ActionKey, LazyNftCardProps, TokenCardInfo } from '@dao-dao/types'
import { getDaoProposalSinglePrefill } from '@dao-dao/utils'

import { useActionForKey } from '../../../actions'
import { useMembership, useWallet } from '../../../hooks'
import {
nftCardInfosForDaoSelector,
lazyNftCardPropsForDaoSelector,
treasuryTokenCardInfosSelector,
} from '../../../recoil'
import {
Expand All @@ -21,7 +21,7 @@ import {
useNativeCommonGovernanceTokenInfoIfExists,
} from '../../../voting-module-adapter'
import { ButtonLink } from '../../ButtonLink'
import { NftCard } from '../../NftCard'
import { LazyNftCard } from '../../NftCard'
import { StargazeNftImportModal } from '../../StargazeNftImportModal'
import { DaoFiatDepositModal } from '../DaoFiatDepositModal'
import { DaoTokenCard } from '../DaoTokenCard'
Expand Down Expand Up @@ -63,7 +63,7 @@ export const TreasuryAndNftsTab = () => {
[]
)
const nfts = useCachedLoading(
nftCardInfosForDaoSelector({
lazyNftCardPropsForDaoSelector({
chainId: daoInfo.chainId,
coreAddress: daoInfo.coreAddress,
governanceCollectionAddress: cw721GovernanceCollectionAddress,
Expand All @@ -87,10 +87,10 @@ export const TreasuryAndNftsTab = () => {
})

return (
<StatelessTreasuryAndNftsTab
<StatelessTreasuryAndNftsTab<TokenCardInfo, LazyNftCardProps>
ButtonLink={ButtonLink}
FiatDepositModal={DaoFiatDepositModal}
NftCard={NftCard}
NftCard={LazyNftCard}
StargazeNftImportModal={StargazeNftImportModal}
TokenCard={DaoTokenCard}
addCollectionHref={
Expand Down
92 changes: 88 additions & 4 deletions packages/stateful/recoil/selectors/nft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from '@dao-dao/state'
import { stakerForNftSelector } from '@dao-dao/state/recoil/selectors/contracts/DaoVotingCw721Staked'
import { ChainId, NftCardInfo, WithChainId } from '@dao-dao/types'
import { LoadingNfts, StargazeNft } from '@dao-dao/types/nft'
import { LazyNftCardProps, LoadingNfts, StargazeNft } from '@dao-dao/types/nft'
import {
MAINNET,
STARGAZE_PROFILE_API_TEMPLATE,
Expand Down Expand Up @@ -100,6 +100,7 @@ export const nftCardInfoWithUriSelector = selectorFamily<
const { name = '', description, imageUrl, externalLink } = metadata || {}

const info: NftCardInfo = {
key: chainId + collection + tokenId,
collection: {
address: collection,
name: collectionInfo.name,
Expand Down Expand Up @@ -153,9 +154,92 @@ export const nftCardInfoSelector = selectorFamily<
},
})

export const lazyNftCardPropsForDaoSelector = selectorFamily<
// Map chain ID to DAO-owned NFTs on that chain.
LoadingNfts<LazyNftCardProps>,
WithChainId<{
coreAddress: string
// If DAO is using the cw721-staking voting module adapter, it will have an
// NFT governance collection. If this is the case, passing it here makes
// sure we include the collection if it is not in the DAO's cw721 token
// list.
governanceCollectionAddress?: string
}>
>({
key: 'lazyNftCardPropsForDao',
get:
({ chainId, coreAddress, governanceCollectionAddress }) =>
async ({ get }) => {
const allNfts = get(
DaoCoreV2Selectors.allCw721CollectionsSelector({
contractAddress: coreAddress,
chainId,
governanceCollectionAddress,
})
)

return Object.entries(allNfts).reduce(
(acc, [chainId, { owner, collectionAddresses }]) => {
collectionAddresses = Array.from(new Set(collectionAddresses))

// Get all token IDs owned by the DAO for each collection.
const nftCollectionTokenIds = get(
waitForNone(
collectionAddresses.map((collectionAddress) =>
CommonNftSelectors.allTokensForOwnerSelector({
contractAddress: collectionAddress,
chainId,
owner,
})
)
)
)

// Get all lazy props for each collection.
const lazyNftCardProps = collectionAddresses.flatMap(
(collectionAddress, index) =>
nftCollectionTokenIds[index].state === 'hasValue'
? (nftCollectionTokenIds[index].contents as string[]).map(
(tokenId): LazyNftCardProps => ({
key: chainId + collectionAddress + tokenId,
chainId,
tokenId,
collectionAddress,
type: 'collection',
})
)
: []
)

return {
...acc,
[chainId]:
nftCollectionTokenIds.length > 0 &&
nftCollectionTokenIds.every(
(loadable) => loadable.state === 'loading'
)
? {
loading: true,
errored: false,
}
: {
loading: false,
errored: false,
updating: nftCollectionTokenIds.some(
(loadable) => loadable.state === 'loading'
),
data: lazyNftCardProps,
},
}
},
{} as LoadingNfts<LazyNftCardProps>
)
},
})

export const nftCardInfosForDaoSelector = selectorFamily<
// Map chain ID to DAO-owned NFTs on that chain.
LoadingNfts,
LoadingNfts<NftCardInfo>,
WithChainId<{
coreAddress: string
// If DAO is using the cw721-staking voting module adapter, it will have an
Expand Down Expand Up @@ -233,7 +317,7 @@ export const nftCardInfosForDaoSelector = selectorFamily<
},
}
},
{} as LoadingNfts
{} as LoadingNfts<NftCardInfo>
)
},
})
Expand All @@ -245,7 +329,7 @@ type CollectionWithTokens = {

// Retrieve all NFTs for a given wallet address using the indexer.
export const walletNftCardInfos = selectorFamily<
LoadingNfts,
LoadingNfts<NftCardInfo>,
WithChainId<{
walletAddress: string
}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useTranslation } from 'react-i18next'

import { CommonNftSelectors } from '@dao-dao/state/recoil'
import { NftsTab, useCachedLoading, useChain } from '@dao-dao/stateless'
import { LazyNftCardProps } from '@dao-dao/types'

import { LazyNftCard } from '../../../../components'
import { useGovernanceCollectionInfo } from '../hooks'
Expand Down Expand Up @@ -29,13 +30,16 @@ export const NftCollectionTab = () => {
? { loading: true }
: {
loading: false,
data: allTokens.data.map((tokenId) => ({
chainId,
collectionAddress,
tokenId,
stakingContractAddress,
key: collectionAddress + tokenId,
})),
data: allTokens.data.map(
(tokenId): LazyNftCardProps & { key: string } => ({
chainId,
collectionAddress,
tokenId,
stakingContractAddress,
key: chainId + collectionAddress + tokenId,
type: 'owner',
})
),
}
}
/>
Expand Down
1 change: 1 addition & 0 deletions packages/stateless/components/NftCard.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const makeProps = (): NftCardProps => {
id++

return {
key: `${id}`,
collection: {
address: 'starsCollectionAddress',
name: 'French Bulldog',
Expand Down
Loading

2 comments on commit be0a0c9

@vercel
Copy link

@vercel vercel bot commented on be0a0c9 Sep 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on be0a0c9 Sep 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.