Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements for NFT media #2643

Merged
merged 11 commits into from
Mar 25, 2025
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
1 change: 1 addition & 0 deletions .github/workflows/deploy-review-l2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ on:
- eth_sepolia
- eth_goerli
- filecoin
- immutable
- neon_devnet
- optimism
- optimism_celestia
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ on:
- eth_sepolia
- eth_goerli
- filecoin
- immutable
- mekong
- neon_devnet
- optimism
Expand Down
1 change: 1 addition & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
"celo_alfajores",
"garnet",
"gnosis",
"immutable",
"eth",
"eth_goerli",
"eth_sepolia",
Expand Down
53 changes: 53 additions & 0 deletions configs/envs/.env.immutable
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Set of ENVs for Immutable network explorer
# https://explorer.immutable.com
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=immutable"

# Local ENVs
NEXT_PUBLIC_APP_PROTOCOL=http
NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws

# Instance ENVs
NEXT_PUBLIC_AD_BANNER_PROVIDER=none
NEXT_PUBLIC_AD_TEXT_PROVIDER=none
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=immutable-mainnet.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEX_POOLS_ENABLED=true
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/immutable-mainnet.json
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/immutable.json
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=0x6166cece570f4731ccc94c2d17d854ce88496cd3b48e03b537959992ab6685c8
NEXT_PUBLIC_HAS_CONTRACT_AUDIT_REPORTS=true
NEXT_PUBLIC_HELIA_VERIFIED_FETCH_ENABLED=false
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['no-repeat center/100% 100% url(https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-skins/immutable.jpg)'],'text_color':['rgba(19, 19, 19, 1)']}
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
NEXT_PUBLIC_LOGOUT_URL=https://blockscout-immutable.us.auth0.com/v2/logout
NEXT_PUBLIC_MARKETPLACE_ENABLED=false
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/pools']
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=IMX
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=IMX
NEXT_PUBLIC_NETWORK_EXPLORERS=[{'title':'GeckoTerminal','logo':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/explorer-logos/geckoterminal.png','baseUrl':'https://www.geckoterminal.com/','paths':{'token':'/immutable-zkevm/pools'}}]
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/immutable-short.svg
NEXT_PUBLIC_NETWORK_ID=13371
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/immutable.svg
NEXT_PUBLIC_NETWORK_NAME=Immutable
NEXT_PUBLIC_NETWORK_RPC_URL=https://rpc.immutable.com/
NEXT_PUBLIC_NETWORK_SHORT_NAME=Immutable
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/immutable.png
NEXT_PUBLIC_STATS_API_HOST=https://stats-immutable-mainnet.k8s.blockscout.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS=["miner"]
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VIEWS_NFT_MARKETPLACES=[{'name':'Rarible','collection_url':'https://rarible.com/collection/immutablex/{hash}/items','instance_url':'https://rarible.com/token/immutablex/{hash}:{id}','logo_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/nft-marketplace-logos/rarible.png'}]
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
13 changes: 9 additions & 4 deletions mocks/tokens/tokenTransfer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { TokenInfo } from 'types/api/token';
import type { TokenTransfer, TokenTransferResponse } from 'types/api/tokenTransfer';

import * as tokenInstanceMock from './tokenInstance';

export const erc20: TokenTransfer = {
from: {
hash: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859',
Expand Down Expand Up @@ -86,6 +88,7 @@ export const erc721: TokenTransfer = {
},
total: {
token_id: '875879856',
token_instance: tokenInstanceMock.base,
},
transaction_hash: '0xf13bc7afe5e02b494dd2f22078381d36a4800ef94a0ccc147431db56c301e6cc',
type: 'token_transfer',
Expand Down Expand Up @@ -135,6 +138,7 @@ export const erc1155A: TokenTransfer = {
token_id: '123',
value: '42',
decimals: null,
token_instance: null,
},
transaction_hash: '0x05d6589367633c032d757a69c5fb16c0e33e3994b0d9d1483f82aeee1f05d746',
type: 'token_minting',
Expand All @@ -151,7 +155,7 @@ export const erc1155B: TokenTransfer = {
name: 'SastanaNFT',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
},
total: { token_id: '12345678', value: '100000000000000000000', decimals: null },
total: { token_id: '12345678', value: '100000000000000000000', decimals: null, token_instance: null },
};

export const erc1155C: TokenTransfer = {
Expand All @@ -161,7 +165,7 @@ export const erc1155C: TokenTransfer = {
name: 'SastanaNFT',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
},
total: { token_id: '483200961027732618117991942553110860267520', value: '200000000000000000000', decimals: null },
total: { token_id: '483200961027732618117991942553110860267520', value: '200000000000000000000', decimals: null, token_instance: null },
};

export const erc1155D: TokenTransfer = {
Expand All @@ -171,7 +175,7 @@ export const erc1155D: TokenTransfer = {
name: 'SastanaNFT',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
},
total: { token_id: '456', value: '42', decimals: null },
total: { token_id: '456', value: '42', decimals: null, token_instance: null },
};

export const erc404A: TokenTransfer = {
Expand Down Expand Up @@ -213,6 +217,7 @@ export const erc404A: TokenTransfer = {
value: '42000000000000000000000000',
decimals: '18',
token_id: null,
token_instance: null,
},
transaction_hash: '0x05d6589367633c032d757a69c5fb16c0e33e3994b0d9d1483f82aeee1f05d746',
type: 'token_transfer',
Expand All @@ -230,7 +235,7 @@ export const erc404B: TokenTransfer = {
name: 'SastanaNFT',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
},
total: { token_id: '4625304364899952' },
total: { token_id: '4625304364899952', token_instance: null },
};

export const mixTokens: TokenTransferResponse = {
Expand Down
2 changes: 2 additions & 0 deletions mocks/txs/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const mintToken: TxStateChange = {
direction: 'from',
total: {
token_id: '15077554365819457090226168288698582604878106156134383525616269766016907608065',
token_instance: null,
},
},
],
Expand Down Expand Up @@ -57,6 +58,7 @@ export const receiveMintedToken: TxStateChange = {
direction: 'to',
total: {
token_id: '15077554365819457090226168288698582604878106156134383525616269766016907608065',
token_instance: null,
},
},
],
Expand Down
3 changes: 3 additions & 0 deletions stubs/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export const TOKEN_TRANSFER_ERC_721: TokenTransfer = {
...TOKEN_TRANSFER_ERC_20,
total: {
token_id: '35870',
token_instance: null,
},
token: TOKEN_INFO_ERC_721,
};
Expand All @@ -120,6 +121,7 @@ export const TOKEN_TRANSFER_ERC_1155: TokenTransfer = {
token_id: '35870',
value: '123',
decimals: '18',
token_instance: null,
},
token: TOKEN_INFO_ERC_1155,
};
Expand All @@ -130,6 +132,7 @@ export const TOKEN_TRANSFER_ERC_404: TokenTransfer = {
token_id: '35870',
value: '123',
decimals: '18',
token_instance: null,
},
token: TOKEN_INFO_ERC_404,
};
Expand Down
1 change: 1 addition & 0 deletions stubs/txStateChanges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const STATE_CHANGE_TOKEN: TxStateChange = {
direction: 'to',
total: {
token_id: '1621395',
token_instance: null,
},
},
],
Expand Down
3 changes: 2 additions & 1 deletion tools/preset-sync/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ const PRESETS = {
eth: 'https://eth.blockscout.com',
eth_goerli: 'https://eth-goerli.blockscout.com',
eth_sepolia: 'https://eth-sepolia.blockscout.com',
garnet: 'https://explorer.garnetchain.com',
filecoin: 'https://filecoin.blockscout.com',
garnet: 'https://explorer.garnetchain.com',
gnosis: 'https://gnosis.blockscout.com',
immutable: 'https://explorer.immutable.com',
mekong: 'https://mekong.blockscout.com',
neon_devnet: 'https://neon-devnet.blockscout.com',
optimism: 'https://optimism.blockscout.com',
Expand Down
4 changes: 3 additions & 1 deletion types/api/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ export interface TokenInstance {
holder_address_hash: string | null;
image_url: string | null;
animation_url: string | null;
media_url?: string | null;
media_type?: string | null;
external_app_url: string | null;
metadata: Record<string, unknown> | null;
owner: AddressParam | null;
thumbnails: Partial<Record<ThumbnailSize, string>> | null;
thumbnails: ({ original: string } & Partial<Record<Exclude<ThumbnailSize, 'original'>, string>>) | null;
}

export interface TokenInstanceMetadataSocketMessage {
Expand Down
6 changes: 5 additions & 1 deletion types/api/tokenTransfer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AddressParam } from './addressParams';
import type { TokenInfo, TokenType } from './token';
import type { TokenInfo, TokenInstance, TokenType } from './token';

export type Erc20TotalPayload = {
decimals: string | null;
Expand All @@ -8,20 +8,24 @@ export type Erc20TotalPayload = {

export type Erc721TotalPayload = {
token_id: string | null;
token_instance: TokenInstance | null;
};

export type Erc1155TotalPayload = {
decimals: string | null;
value: string;
token_id: string | null;
token_instance: TokenInstance | null;
};

export type Erc404TotalPayload = {
decimals: string;
value: string;
token_id: null;
token_instance: TokenInstance | null;
} | {
token_id: string;
token_instance: TokenInstance | null;
};

export type TokenTransfer = (
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ui/address/tokens/NFTItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const NFTItem = ({ token, value, isLoading, withTokenLink, ...tokenInstance }: P
<NftMedia
mb="18px"
data={ tokenInstance }
size="md"
isLoading={ isLoading }
autoplayVideo={ false }
/>
Expand Down
10 changes: 9 additions & 1 deletion ui/pages/TokenInstance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,15 @@ const TokenInstanceContent = () => {
{
id: 'token_transfers',
title: 'Token transfers',
component: <TokenTransfer transfersQuery={ transfersQuery } tokenId={ id } tokenQuery={ tokenQuery } shouldRender={ !isLoading }/>,
component: (
<TokenTransfer
transfersQuery={ transfersQuery }
tokenId={ id }
tokenQuery={ tokenQuery }
tokenInstance={ tokenInstanceQuery.data }
shouldRender={ !isLoading }
/>
),
},
shouldFetchHolders ?
{ id: 'holders', title: 'Holders', component: <TokenHolders holdersQuery={ holdersQuery } token={ tokenQuery.data } shouldRender={ !isLoading }/> } :
Expand Down
4 changes: 3 additions & 1 deletion ui/pages/TokenTransfers.pw.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Box } from '@chakra-ui/react';
import React from 'react';

import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import { mixTokens } from 'mocks/tokens/tokenTransfer';
import { test, expect } from 'playwright/lib';

import TokenTransfers from './TokenTransfers';

test('base view +@mobile', async({ render, mockTextAd, mockApiResponse }) => {
test('base view +@mobile', async({ render, mockTextAd, mockApiResponse, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
await mockTextAd();
await mockApiResponse('token_transfers_all', mixTokens, { queryParams: { type: [] } });
const component = await render(<Box pt={{ base: '106px', lg: 0 }}> <TokenTransfers/> </Box>);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions ui/shared/TokenTransfer/TokenTransferList.pw.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Box } from '@chakra-ui/react';
import React from 'react';

import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
import { test, expect, devices } from 'playwright/lib';

Expand All @@ -23,7 +24,8 @@ const data = [
tokenTransferMock.erc1155D,
];

test('without tx info', async({ render }) => {
test('without tx info', async({ render, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render(
<Box pt={{ base: '134px', lg: 6 }}>
<TokenTransferList
Expand All @@ -36,7 +38,8 @@ test('without tx info', async({ render }) => {
await expect(component).toHaveScreenshot();
});

test('with tx info', async({ render }) => {
test('with tx info', async({ render, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render(
<Box pt={{ base: '134px', lg: 6 }}>
<TokenTransferList
Expand Down
2 changes: 1 addition & 1 deletion ui/shared/TokenTransfer/TokenTransferListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const TokenTransferListItem = ({
) }
</Flex>
{ total && 'token_id' in total && total.token_id !== null && token && (
<NftEntity hash={ token.address } id={ total.token_id } isLoading={ isLoading }/>
<NftEntity hash={ token.address } id={ total.token_id } instance={ total.token_instance } isLoading={ isLoading }/>
) }
{ showTxInfo && txHash && (
<Flex justifyContent="space-between" alignItems="center" lineHeight="24px" width="100%">
Expand Down
7 changes: 5 additions & 2 deletions ui/shared/TokenTransfer/TokenTransferTable.pw.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Box } from '@chakra-ui/react';
import React from 'react';

import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
import { test, expect } from 'playwright/lib';

import TokenTransferTable from './TokenTransferTable';

test('without tx info', async({ render }) => {
test('without tx info', async({ render, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render(
<Box pt={{ base: '134px', lg: 6 }}>
<TokenTransferTable
Expand All @@ -20,7 +22,8 @@ test('without tx info', async({ render }) => {
await expect(component).toHaveScreenshot();
});

test('with tx info', async({ render }) => {
test('with tx info', async({ render, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render(
<Box pt={{ base: '134px', lg: 6 }}>
<TokenTransferTable
Expand Down
1 change: 1 addition & 0 deletions ui/shared/TokenTransfer/TokenTransferTableItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ const TokenTransferTableItem = ({
<NftEntity
hash={ token.address }
id={ total.token_id }
instance={ total.token_instance }
isLoading={ isLoading }
/>
) }
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions ui/shared/TokenTransferSnippet/TokenTransferSnippet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const TokenTransferSnippet = ({ data, isLoading, noAddressIcons = true }: Props)
<TokenTransferSnippetNft
token={ data.token }
tokenId={ total.token_id }
instance={ total.token_instance }
value="1"
/>
);
Expand All @@ -56,6 +57,7 @@ const TokenTransferSnippet = ({ data, isLoading, noAddressIcons = true }: Props)
key={ total.token_id }
token={ data.token }
tokenId={ total.token_id }
instance={ total.token_instance }
value={ total.value }
/>
);
Expand Down
Loading