Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,32 @@ function formatAmountWithLocale(
asset: TransactionAsset,
formatNumberOrString: LocalizationContextState['formatNumberOrString'],
): string {
// For NFTs, prefer the Blockaid summary (e.g. "BAYC #8817") or construct
// a label from symbol/name + token ID so users can identify the specific item.
if (!asset.amount) {
return asset.symbol ?? asset.name ?? ''
if (asset.summary) {
return asset.summary
}
const label = asset.symbol ?? asset.name ?? ''
if (asset.tokenId) {
return label ? `${label} #${asset.tokenId}` : `#${asset.tokenId}`
}
return label
}

const formattedAmount = formatNumberOrString({
value: asset.amount,
type: NumberType.TokenNonTx,
})

// For ERC1155 with quantity and token ID, show both
if (asset.tokenId) {
const label = asset.symbol ?? asset.name ?? ''
return label
? `${formattedAmount} ${label} #${asset.tokenId}`
: `${formattedAmount} #${asset.tokenId}`
}

return `${formattedAmount} ${asset.symbol ?? ''}`
}

Expand Down
4 changes: 4 additions & 0 deletions packages/wallet/src/features/dappRequests/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ export interface TransactionAsset {
logoUrl?: string
/** Spender address (for approvals) */
spenderAddress?: string
/** NFT token ID from Blockaid scan (ERC721/ERC1155) */
tokenId?: string
/** Human-readable summary from Blockaid scan (e.g. "BAYC #8817") */
summary?: string
}

/**
Expand Down
158 changes: 156 additions & 2 deletions packages/wallet/src/features/dappRequests/utils/blockaidUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,102 @@ describe('blockaidUtils', () => {
})
})

describe('parseReceivingAssets', () => {

it('should parse ERC721 sending assets with token_id and summary', () => {
const assetsDiffs = [
{
asset: {
type: 'ERC721',
symbol: 'BAYC',
name: 'Bored Ape Yacht Club',
address: '0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d',
logo_url: 'https://example.com/bayc.png',
chain_id: 1,
},
out: [
{
token_id: '8817',
summary: 'BAYC #8817',
usd_price: '50000',
},
],
in: [],
},
] as any

const result = parseSendingAssets(assetsDiffs, TEST_CHAIN_ID)

expect(result).not.toBeNull()
expect(result?.type).toBe(TransactionSectionType.Sending)
expect(result?.assets).toHaveLength(1)
expect(result?.assets[0]).toEqual({
type: 'ERC721',
symbol: 'BAYC',
name: 'Bored Ape Yacht Club',
amount: undefined,
usdValue: '50000',
logoUrl: 'https://example.com/bayc.png',
address: '0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d',
chainId: TEST_CHAIN_ID,
tokenId: '8817',
summary: 'BAYC #8817',
})
})

it('should parse ERC1155 sending assets with token_id and value', () => {
const assetsDiffs = [
{
asset: {
type: 'ERC1155',
symbol: 'ITEMS',
name: 'Game Items',
address: '0x1155contract',
logo_url: 'https://example.com/items.png',
chain_id: 1,
},
out: [
{
value: '3',
token_id: '42',
usd_price: '150',
},
],
in: [],
},
] as any

const result = parseSendingAssets(assetsDiffs, TEST_CHAIN_ID)

expect(result?.assets[0]?.tokenId).toBe('42')
expect(result?.assets[0]?.amount).toBe('3')
})

it('should not add tokenId for ERC20 assets even if token_id is present in response', () => {
const assetsDiffs = [
{
asset: {
type: 'ERC20',
symbol: 'USDC',
name: 'USD Coin',
address: '0xusdc',
chain_id: 1,
},
out: [
{
value: '100',
token_id: 'unexpected',
},
],
in: [],
},
] as any

const result = parseSendingAssets(assetsDiffs, TEST_CHAIN_ID)

expect(result?.assets[0]?.tokenId).toBeUndefined()
})

describe('parseReceivingAssets', () => {
it('should return null when no assets are being received', () => {
const assetsDiffs = [
{
Expand Down Expand Up @@ -339,7 +434,66 @@ describe('blockaidUtils', () => {
})
})

describe('parseApprovals', () => {

it('should parse ERC721 receiving assets with token_id and summary', () => {
const assetsDiffs = [
{
asset: {
type: 'ERC721',
symbol: 'PUNK',
name: 'CryptoPunks',
address: '0xpunks',
logo_url: 'https://example.com/punk.png',
chain_id: 1,
},
out: [],
in: [
{
token_id: '3100',
summary: 'CryptoPunk #3100',
usd_price: '75000',
},
],
},
] as any

const result = parseReceivingAssets(assetsDiffs, TEST_CHAIN_ID)

expect(result).not.toBeNull()
expect(result?.type).toBe(TransactionSectionType.Receiving)
expect(result?.assets[0]?.tokenId).toBe('3100')
expect(result?.assets[0]?.summary).toBe('CryptoPunk #3100')
expect(result?.assets[0]?.amount).toBeUndefined()
})

it('should parse ERC1155 receiving assets with token_id and value', () => {
const assetsDiffs = [
{
asset: {
type: 'ERC1155',
symbol: 'LAND',
name: 'Sandbox Land',
address: '0xland',
chain_id: 1,
},
out: [],
in: [
{
value: '5',
token_id: '99',
usd_price: '500',
},
],
},
] as any

const result = parseReceivingAssets(assetsDiffs, TEST_CHAIN_ID)

expect(result?.assets[0]?.tokenId).toBe('99')
expect(result?.assets[0]?.amount).toBe('5')
})

describe('parseApprovals', () => {
it('should return null when no exposures exist', () => {
const exposures = [] as any

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ export function parseSendingAssets(assetsDiffs: AssetDiffs, chainId: UniverseCha
}
const asset = assetDiff.asset

const isNft = asset.type === 'ERC721' || asset.type === 'ERC1155'

sendingAssets.push({
type: asset.type,
symbol: asset.symbol,
Expand All @@ -248,6 +250,8 @@ export function parseSendingAssets(assetsDiffs: AssetDiffs, chainId: UniverseCha
logoUrl: asset.logo_url,
address: getAssetAddress(asset),
chainId,
...(isNft && outAmount.token_id ? { tokenId: String(outAmount.token_id) } : {}),
...(isNft && outAmount.summary ? { summary: outAmount.summary } : {}),
})
}
})
Expand Down Expand Up @@ -276,6 +280,8 @@ export function parseReceivingAssets(assetsDiffs: AssetDiffs, chainId: UniverseC
}
const asset = assetDiff.asset

const isNft = asset.type === 'ERC721' || asset.type === 'ERC1155'

receivingAssets.push({
type: asset.type,
symbol: asset.symbol,
Expand All @@ -285,6 +291,8 @@ export function parseReceivingAssets(assetsDiffs: AssetDiffs, chainId: UniverseC
logoUrl: asset.logo_url,
address: getAssetAddress(asset),
chainId,
...(isNft && inAmount.token_id ? { tokenId: String(inAmount.token_id) } : {}),
...(isNft && inAmount.summary ? { summary: inAmount.summary } : {}),
})
}
})
Expand Down