Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tender-walls-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'alephium-desktop-wallet': patch
---

Fix display of NFT when minting
5 changes: 5 additions & 0 deletions .changeset/whole-aliens-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@alephium/mobile-wallet': patch
---

Fix display of NFT when minting
1 change: 1 addition & 0 deletions apps/desktop-wallet/src/components/TokenAmountsBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ interface AssetAmountRowProps extends AmountBaseProps {
tokenId: string
amount: string
extraAlphForDust: bigint
skipCaching?: boolean
}

const AssetAmountRow = ({ tokenId, amount, extraAlphForDust, ...props }: AssetAmountRowProps) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import { TransactionDisplayProps } from '@/features/transactionsDisplay/transact
interface TransactionSummaryProps extends TransactionDisplayProps {
hideType?: boolean
className?: string
skipCaching?: boolean
}

const TransactionSummary = ({ tx, referenceAddress, hideType, className }: TransactionSummaryProps) => (
const TransactionSummary = ({ tx, referenceAddress, hideType, className, skipCaching }: TransactionSummaryProps) => (
<SummaryStyled className={className}>
<SummaryContent>
{!hideType && <TransactionType tx={tx} referenceAddress={referenceAddress} />}
<TransactionAmounts tx={tx} referenceAddress={referenceAddress} />
<TransactionAmounts tx={tx} referenceAddress={referenceAddress} skipCaching={skipCaching} />
</SummaryContent>
</SummaryStyled>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { useTransactionAmountDeltas, useTransactionInfoType } from '@alephium/shared-react'
import { NOCACHE_PREFIX, useTransactionAmountDeltas, useTransactionInfoType } from '@alephium/shared-react'
import { ALPH } from '@alephium/token-list'
import { useMemo } from 'react'

import TokenAmountsBox from '@/components/TokenAmountsBox'
import { TransactionDisplayProps } from '@/features/transactionsDisplay/transactionDisplayTypes'

const TransactionAmounts = ({ tx, referenceAddress }: TransactionDisplayProps) => {
const TransactionAmounts = ({
tx,
referenceAddress,
skipCaching
}: TransactionDisplayProps & { skipCaching?: boolean }) => {
const { alphAmount, tokenAmounts } = useTransactionAmountDeltas(tx, referenceAddress)
const assetAmounts = useMemo(
() => (alphAmount !== BigInt(0) ? [{ id: ALPH.id, amount: alphAmount }, ...tokenAmounts] : tokenAmounts),
[alphAmount, tokenAmounts]
)
const assetAmounts = useMemo(() => {
const _tokenAmounts = tokenAmounts.map((t) => ({ ...t, id: skipCaching ? `${NOCACHE_PREFIX}${t.id}` : t.id }))
return alphAmount !== BigInt(0) ? [{ id: ALPH.id, amount: alphAmount }, ..._tokenAmounts] : _tokenAmounts
}, [alphAmount, skipCaching, tokenAmounts])

const infoType = useTransactionInfoType({ tx, referenceAddress: referenceAddress, view: 'wallet' })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const SimulatedResult = ({
<SectionTitle>{t('Simulated result')}</SectionTitle>
{isRelevant ? (
<>
<TransactionSummaryStyled tx={unsignedData} referenceAddress={txParams.signerAddress} hideType />
<TransactionSummaryStyled tx={unsignedData} referenceAddress={txParams.signerAddress} hideType skipCaching />
<Box hasBg hasHorizontalPadding>
<AddressesDataRows tx={unsignedData} referenceAddress={txParams.signerAddress} />
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ const SimulatedResult = ({
/>
</Row>
)}
<TransactionAmounts tx={unsignedData} referenceAddress={txParams.signerAddress} isLast />
<TransactionAmounts tx={unsignedData} referenceAddress={txParams.signerAddress} isLast skipCaching />
</>
) : (
<AppText style={{ textAlign: 'center', marginTop: DEFAULT_MARGIN }} color="secondary">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,16 @@ const TransactionStatus = ({ tx }: Pick<TransactionModalSubcomponentProps, 'tx'>

interface TransactionAmountsProps extends TransactionModalSubcomponentProps {
isLast?: boolean
skipCaching?: boolean
}

export const TransactionAmounts = ({ tx, referenceAddress, isLast }: TransactionAmountsProps) => {
export const TransactionAmounts = ({ tx, referenceAddress, isLast, skipCaching }: TransactionAmountsProps) => {
const { t } = useTranslation()
const theme = useTheme()
const dispatch = useAppDispatch()
const {
data: { fungibleTokens, nfts, nsts }
} = useFetchTransactionTokens(tx, referenceAddress)
} = useFetchTransactionTokens(tx, referenceAddress, skipCaching)
const infoType = useTransactionInfoType({ tx, referenceAddress, view: 'wallet' })

const groupedFtAmounts = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { useQuery } from '@tanstack/react-query'
import { tokenQuery } from '@/api/queries/tokenQueries'
import { useCurrentlyOnlineNetworkId } from '@/network'

export const useFetchToken = (id: TokenId) => {
export const useFetchToken = (id: TokenId, skipCaching?: boolean) => {
const networkId = useCurrentlyOnlineNetworkId()

const { data, isLoading } = useQuery(tokenQuery({ id, networkId }))
const { data, isLoading } = useQuery(tokenQuery({ id, networkId, skipCaching }))

return {
data,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ type TransactionTokens = {

export const useFetchTransactionTokens = (
tx: e.Transaction | e.PendingTransaction | SentTransaction | ExecuteScriptTx,
addressHash: AddressHash
addressHash: AddressHash,
skipCaching: boolean = false
): TransactionTokens => {
const networkId = useCurrentlyOnlineNetworkId()
const { alphAmount, tokenAmounts } = useTransactionAmountDeltas(tx, addressHash)

const { data: tokens, isLoading } = useQueries({
queries: tokenAmounts.map(({ id }) => tokenQuery({ id, networkId })),
queries: tokenAmounts.map(({ id }) => tokenQuery({ id, networkId, skipCaching })),
combine: (results) => combineTokens(results, tokenAmounts)
})

Expand Down
8 changes: 5 additions & 3 deletions packages/shared-react/src/api/apiUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
AddressWithGroup,
getMissingBalancesChainedTxParams,
getTransactionExpectedBalances,
ONE_MINUTE_MS,
TokenId,
TransactionParams,
UnlistedFT
Expand All @@ -16,11 +17,12 @@ interface GetQueryConfigProps {
gcTime: number
staleTime?: number
networkId?: number
skipCaching?: boolean
}

export const getQueryConfig = ({ staleTime, gcTime, networkId }: GetQueryConfigProps) => ({
staleTime,
gcTime,
export const getQueryConfig = ({ staleTime, gcTime, networkId, skipCaching }: GetQueryConfigProps) => ({
staleTime: skipCaching ? 0 : staleTime,
gcTime: skipCaching ? ONE_MINUTE_MS : gcTime,
meta: { isMainnet: networkId === 0 }
})

Expand Down
65 changes: 41 additions & 24 deletions packages/shared-react/src/api/queries/tokenQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const StdInterfaceIds = Object.values(e.TokenStdInterfaceId)
interface TokenQueryProps extends SkipProp {
id: TokenId
networkId?: number
skipCaching?: boolean
}

interface NFTQueryProps extends TokenQueryProps {
Expand Down Expand Up @@ -82,12 +83,12 @@ export const ftListQuery = ({ networkId, skip }: Omit<TokenQueryProps, 'id'>) =>
})
}

export const tokenTypeQuery = ({ id, networkId, skip }: TokenQueryProps) =>
export const tokenTypeQuery = ({ id, networkId, skip, skipCaching }: TokenQueryProps) =>
queryOptions({
queryKey: ['token', 'type', id],
queryKey: ['token', 'type', getId(id, skipCaching)],
// We always want to remember the type of a token, even when user navigates for too long from components that use
// tokens.
...getQueryConfig({ staleTime: Infinity, gcTime: Infinity, networkId }),
...getQueryConfig({ staleTime: Infinity, gcTime: Infinity, networkId, skipCaching }),
queryFn:
!skip && networkId !== undefined
? async () => {
Expand Down Expand Up @@ -127,10 +128,10 @@ export const combineTokenTypes = (tokenTypes: (e.TokenInfo | { data: e.TokenInfo
} as Record<e.TokenStdInterfaceId, TokenId[]>
)

export const fungibleTokenMetadataQuery = ({ id, networkId, skip }: TokenQueryProps) =>
export const fungibleTokenMetadataQuery = ({ id, networkId, skip, skipCaching }: TokenQueryProps) =>
queryOptions({
queryKey: ['token', 'fungible', 'metadata', id],
...getQueryConfig({ staleTime: Infinity, gcTime: Infinity, networkId }),
queryKey: ['token', 'fungible', 'metadata', getId(id, skipCaching)],
...getQueryConfig({ staleTime: Infinity, gcTime: Infinity, networkId, skipCaching }),
queryFn: !skip
? async () => {
const tokenMetadata = await batchers.ftMetadataBatcher.fetch(id)
Expand All @@ -140,18 +141,18 @@ export const fungibleTokenMetadataQuery = ({ id, networkId, skip }: TokenQueryPr
: skipToken
})

export const nftMetadataQuery = ({ id, networkId, skip }: TokenQueryProps) =>
export const nftMetadataQuery = ({ id, networkId, skip, skipCaching }: TokenQueryProps) =>
queryOptions({
queryKey: ['token', 'non-fungible', 'metadata', id],
...getQueryConfig({ staleTime: Infinity, gcTime: Infinity, networkId }),
queryKey: ['token', 'non-fungible', 'metadata', getId(id, skipCaching)],
...getQueryConfig({ staleTime: Infinity, gcTime: Infinity, networkId, skipCaching }),
queryFn: !skip ? async () => (await batchers.nftMetadataBatcher.fetch(id)) ?? null : skipToken
})

export const nftDataQuery = ({ id, tokenUri, networkId, skip }: NFTQueryProps) =>
export const nftDataQuery = ({ id, tokenUri, networkId, skip, skipCaching }: NFTQueryProps) =>
queryOptions({
queryKey: ['token', 'non-fungible', 'data', id],
queryKey: ['token', 'non-fungible', 'data', getId(id, skipCaching)],
// We don't want to delete the NFT data when the user navigates away from NFT components.
...getQueryConfig({ staleTime: ONE_DAY_MS, gcTime: Infinity, networkId }),
...getQueryConfig({ staleTime: ONE_DAY_MS, gcTime: Infinity, networkId, skipCaching }),
queryFn:
!skip && !!tokenUri
? async () => {
Expand Down Expand Up @@ -203,10 +204,21 @@ export const nftDataQuery = ({ id, tokenUri, networkId, skip }: NFTQueryProps) =
: skipToken
})

export const tokenQuery = ({ id, networkId, skip }: TokenQueryProps) =>
queryOptions({
queryKey: ['token', id, { networkId }],
...getQueryConfig({ staleTime: Infinity, gcTime: Infinity, networkId }),
export const NOCACHE_PREFIX = 'nocache-'

export const tokenQuery = ({ id: dirtyId, networkId, skip, skipCaching: skipCachingProp }: TokenQueryProps) => {
const isDirtyId = dirtyId.includes(NOCACHE_PREFIX)
Copy link
Member

Choose a reason for hiding this comment

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

Nit: we could use .startsWith to be a bit more clear / precise.

const id = isDirtyId ? dirtyId.split(NOCACHE_PREFIX)[1] : dirtyId
const skipCaching = isDirtyId || skipCachingProp

return queryOptions({
queryKey: ['token', getId(id, skipCaching), { networkId }],
...getQueryConfig({
staleTime: Infinity,
gcTime: Infinity,
networkId,
skipCaching
}),
queryFn: async (): Promise<Token> => {
const nst = { id } as NonStandardToken

Expand All @@ -218,18 +230,18 @@ export const tokenQuery = ({ id, networkId, skip }: TokenQueryProps) =>
if (listedFT) return listedFT

// 2. If not, find the type of the token
const tokenInfo = await queryClient.fetchQuery(tokenTypeQuery({ id, networkId }))
const tokenInfo = await queryClient.fetchQuery(tokenTypeQuery({ id, networkId, skipCaching }))

// 3. If it is a fungible token, fetch the fungible token metadata
if (tokenInfo?.stdInterfaceId === e.TokenStdInterfaceId.Fungible) {
const ftMetadata = await queryClient.fetchQuery(fungibleTokenMetadataQuery({ id, networkId }))
const ftMetadata = await queryClient.fetchQuery(fungibleTokenMetadataQuery({ id, networkId, skipCaching }))

return ftMetadata ?? nst
}

// 4. If it is an NFT, fetch the NFT metadata and data
if (tokenInfo?.stdInterfaceId === e.TokenStdInterfaceId.NonFungible) {
const nft = await queryClient.fetchQuery(nftQuery({ id, networkId }))
const nft = await queryClient.fetchQuery(nftQuery({ id, networkId, skipCaching }))

return nft ?? nst
}
Expand All @@ -246,21 +258,26 @@ export const tokenQuery = ({ id, networkId, skip }: TokenQueryProps) =>
},
enabled: !skip
})
}

export const nftQuery = ({ id, networkId, skip }: TokenQueryProps) =>
export const nftQuery = ({ id, networkId, skip, skipCaching }: TokenQueryProps) =>
queryOptions({
queryKey: ['token', 'non-fungible', id, { networkId }],
...getQueryConfig({ staleTime: Infinity, gcTime: Infinity, networkId }),
queryKey: ['token', 'non-fungible', getId(id, skipCaching), { networkId }],
...getQueryConfig({ staleTime: Infinity, gcTime: Infinity, networkId, skipCaching }),
queryFn: async (): Promise<NFT | null> => {
const nftMetadata = await queryClient.fetchQuery(nftMetadataQuery({ id, networkId }))
const nftMetadata = await queryClient.fetchQuery(nftMetadataQuery({ id, networkId, skipCaching }))

if (!nftMetadata) return null

const nftData = await queryClient.fetchQuery(nftDataQuery({ id, tokenUri: nftMetadata.tokenUri, networkId }))
const nftData = await queryClient.fetchQuery(
nftDataQuery({ id, tokenUri: nftMetadata.tokenUri, networkId, skipCaching })
)

if (!nftData) return null

return { ...nftData, ...nftMetadata }
},
enabled: !skip
})

const getId = (id: string, skipCaching?: boolean) => `${skipCaching ? NOCACHE_PREFIX : ''}${id}`
Loading