Skip to content

Commit

Permalink
add icons to contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
NahuelNoves committed Mar 13, 2024
1 parent 3c288c6 commit fd3dfa7
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 10 deletions.
13 changes: 12 additions & 1 deletion ui/tx/assetFlows/components/NovesSubHeadingInterpretation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { Fragment } from 'react';

import type { NovesResponseData } from 'types/api/noves';

import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import IconSvg from 'ui/shared/IconSvg';
import { getDescriptionItems } from 'ui/tx/assetFlows/utils/getDescriptionItems';
Expand Down Expand Up @@ -61,7 +62,17 @@ const NovesSubHeadingInterpretation: FC<Props> = ({ data, isLoading }) => {
fontSize="lg"
w="fit-content"
/>
) }
)
}
{
item.address && (
<AddressEntity
address={{ hash: item.address, is_contract: true, is_verified: true }}
truncation="constant"
whiteSpace="initial"
/>
)
}
</Fragment>
)) }
</Box>
Expand Down
21 changes: 20 additions & 1 deletion ui/tx/assetFlows/utils/getDescriptionItems.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,28 @@ it('creates sub heading items to render', async() => {

expect(result).toEqual([
{
text: ' Called function \'stake\' on contract 0xef326CdAdA59D3A740A76bB5f4F88Fb2',
token: undefined,
text: ' ',
hasId: false,
type: 'action',
actionText: 'Called function',
address: undefined,
},
{
token: undefined,
text: '\'stake\' ',
hasId: false,
type: 'action',
actionText: 'on contract',
address: undefined,
},
{
token: undefined,
text: '',
hasId: false,
type: 'contract',
actionText: undefined,
address: '0xef326cdada59d3a740a76bb5f4f88fb2f1076164',
},
]);
});
50 changes: 42 additions & 8 deletions ui/tx/assetFlows/utils/getDescriptionItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface TokenWithIndices {
hasId: boolean;
indices: Array<number>;
token?: NovesTokenInfo;
type?: 'action';
type?: 'action' | 'contract';
}

export interface DescriptionItems {
Expand All @@ -19,8 +19,11 @@ export interface DescriptionItems {
hasId: boolean | undefined;
type?: string;
actionText?: string;
address?: string;
}

const CONTRACT_REGEXP = /(0x[\da-fA-F]{32}\b)/g;

export const getDescriptionItems = (translateData: NovesResponseData): Array<DescriptionItems> => {

// Remove final dot and add space at the start to avoid matching issues
Expand All @@ -33,9 +36,11 @@ export const getDescriptionItems = (translateData: NovesResponseData): Array<Des
const tokensMatchedByName = tokenData.nameList.filter(name => parsedDescription.toUpperCase().includes(` ${ name.toUpperCase() }`));
let tokensMatchedBySymbol = tokenData.symbolList.filter(symbol => parsedDescription.toUpperCase().includes(` ${ symbol.toUpperCase() }`));

const actions = [ 'sent', 'Sent', 'Called function', 'called function', 'on contract' ];
const actions = [ 'sent', 'Sent', 'Called function', 'called function', 'on contract', 'swap', 'Swap' ];
const actionsMatched = actions.filter(action => parsedDescription.includes(action));

const contractMatched = parsedDescription.match(CONTRACT_REGEXP) || [];

// Filter symbols if they're already matched by name
tokensMatchedBySymbol = tokensMatchedBySymbol.filter(symbol => !tokensMatchedByName.includes(tokenData.bySymbol[symbol]?.name || ''));

Expand All @@ -44,6 +49,7 @@ export const getDescriptionItems = (translateData: NovesResponseData): Array<Des
let tokensBySymbol;

let tokensByAction;
let tokensByContract;

if (idsMatched.length) {
parsedDescription = removeIds(tokensMatchedByName, tokensMatchedBySymbol, idsMatched, tokenData, parsedDescription);
Expand All @@ -67,9 +73,15 @@ export const getDescriptionItems = (translateData: NovesResponseData): Array<Des
tokensByAction.forEach(i => indices.push(...i.indices));
}

if (contractMatched.length) {
tokensByContract = parseTokensByContract(contractMatched, parsedDescription, translateData);

tokensByContract.forEach(i => indices.push(...i.indices));
}

const indicesSorted = _.uniq(indices.sort((a, b) => a - b));

const tokensWithIndices = _.uniqBy(_.concat(tokensByName, tokensBySymbol, tokensByAction), 'name');
const tokensWithIndices = _.uniqBy(_.concat(tokensByName, tokensBySymbol, tokensByAction, tokensByContract), 'name');

return createDescriptionItems(indicesSorted, tokensWithIndices, parsedDescription);
};
Expand Down Expand Up @@ -146,7 +158,7 @@ const parseTokensBySymbol = (tokensMatchedBySymbol: Array<string>, idsMatched: A
};

const parseTokensByAction = (actionsMatched: Array<string>, parsedDescription: string) => {
const tokensBySymbol: Array<TokenWithIndices> = actionsMatched.map(action => {
const tokensByAction: Array<TokenWithIndices> = actionsMatched.map(action => {
return {
name: action,
indices: [ ...parsedDescription.matchAll(new RegExp(action, 'gi')) ].map(a => a.index) as unknown as Array<number>,
Expand All @@ -155,7 +167,25 @@ const parseTokensByAction = (actionsMatched: Array<string>, parsedDescription: s
};
});

return tokensBySymbol;
return tokensByAction;
};

const parseTokensByContract = (contractMatched: Array<string>, parsedDescription: string, translateData: NovesResponseData) => {
const toAddress = translateData.rawTransactionData.toAddress.toLowerCase();
const contractFiltered = contractMatched.filter(contract => toAddress.startsWith(contract.toLowerCase()))[0];

if (!contractFiltered) {
return [];
}

const tokensByContract: Array<TokenWithIndices> = [ {
name: toAddress,
indices: [ ...parsedDescription.matchAll(new RegExp(contractFiltered, 'gi')) ].map(a => a.index) as unknown as Array<number>,
hasId: false,
type: 'contract',
} ];

return tokensByContract;
};

const createDescriptionItems = (indicesSorted: Array<number>, tokensWithIndices: Array<TokenWithIndices | undefined>, parsedDescription: string) => {
Expand All @@ -167,26 +197,30 @@ const createDescriptionItems = (indicesSorted: Array<number>, tokensWithIndices:

if (i === 0) {
const isAction = item?.type === 'action';
const isContract = item?.type === 'contract';

token = {
token: item?.token,
text: parsedDescription.substring(0, endIndex),
hasId: item?.hasId,
type: isAction ? 'action' : undefined,
type: item?.type,
actionText: isAction ? item.name : undefined,
address: isContract ? item.name : undefined,
};
} else {
const previousItem = tokensWithIndices.find(t => t?.indices.includes(indicesSorted[i - 1]));
// Add the length of the text of the previous token to remove it from the start
const startIndex = indicesSorted[i - 1] + (previousItem?.name.length || 0) + 1;
const isAction = item?.type === 'action';
const isContract = item?.type === 'contract';

token = {
token: item?.token,
text: parsedDescription.substring(startIndex, endIndex),
hasId: item?.hasId,
type: isAction ? 'action' : undefined,
type: item?.type,
actionText: isAction ? item.name : undefined,
address: isContract ? item.name : undefined,
};
}

Expand All @@ -199,7 +233,7 @@ const createDescriptionItems = (indicesSorted: Array<number>, tokensWithIndices:

// Check if there is text left after the last token and push it to the array
if (restString) {
descriptionItems.push({ text: restString, token: undefined, hasId: false, type: undefined, actionText: undefined });
descriptionItems.push({ text: restString, token: undefined, hasId: false, type: undefined, actionText: undefined, address: undefined });
}

return descriptionItems;
Expand Down

0 comments on commit fd3dfa7

Please sign in to comment.