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

Noves integration #1398

Merged
merged 38 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5947511
noves integration
juanlenoves Dec 6, 2023
96e2def
code refactored
NahuelNoves Dec 31, 2023
df51e51
Merge branch 'main' into noves
NahuelNoves Jan 16, 2024
18230d4
Merge main into noves - pull changes from blockscout
NahuelNoves Jan 16, 2024
0fca6be
PR changes added
NahuelNoves Jan 30, 2024
e29e77b
Code set up for new proxy 'describeTxs'
NahuelNoves Feb 2, 2024
8c4a911
minor fix
NahuelNoves Feb 2, 2024
8f4b695
Merge branch 'main' into noves
NahuelNoves Feb 6, 2024
6a7a1ba
Rename Novestranslate.ts to NovesTranslate.ts
juanlenoves Feb 8, 2024
e03304a
some quick stuff
juanlenoves Feb 8, 2024
32b7cf5
Merge branch 'main' into noves
juanlenoves Feb 8, 2024
0875d00
partial fixes and commit for changing how useDescribeTxs and txsConte…
juanlenoves Feb 9, 2024
67f9821
Pending PR fixes
NahuelNoves Feb 12, 2024
ba04f7b
tx asset flows pageSize of 50
juanlenoves Feb 12, 2024
d857327
PR comments fixes
NahuelNoves Feb 17, 2024
2dc925d
rename expected api endpoint for the describe_txs endpoint, more accu…
juanlenoves Feb 18, 2024
926ed8b
one final re-name for api endpoint (make it clear it's an object vs a…
juanlenoves Feb 18, 2024
8d66a3e
scrollRef fix
NahuelNoves Feb 20, 2024
830665a
Merge branch 'main' into noves
NahuelNoves Feb 20, 2024
85b006a
build error fix
NahuelNoves Feb 23, 2024
b68a924
design fixes
NahuelNoves Mar 3, 2024
bac02c0
Merge branch 'main' into noves
NahuelNoves Mar 3, 2024
fe5875f
sub heading fix
NahuelNoves Mar 3, 2024
ad72727
Removed pagination in account history
francisco-noves Mar 5, 2024
b0a21ac
remove duplicate route
juanlenoves Mar 6, 2024
79e7316
updated table theme and icon gap
francisco-noves Mar 7, 2024
48cf473
Removed wrong color in table
francisco-noves Mar 7, 2024
9aeb7d6
removed null validation in page params
francisco-noves Mar 8, 2024
301ff00
updated margin
francisco-noves Mar 11, 2024
674f102
margin fix
NahuelNoves Mar 12, 2024
3c288c6
Merge branch 'main' into noves
NahuelNoves Mar 12, 2024
fd3dfa7
add icons to contracts
NahuelNoves Mar 13, 2024
aa7bd83
Sub-heading interpretation simplified
NahuelNoves Mar 20, 2024
fd90cf1
token alignment fix
NahuelNoves Mar 20, 2024
cb0d8e7
tests added for new functions
NahuelNoves Mar 20, 2024
d19d1f3
Merge branch 'main' into noves
NahuelNoves Mar 20, 2024
0c74939
margin fix
NahuelNoves Mar 20, 2024
b18f25d
remove divider on mobile asset flows
NahuelNoves Mar 22, 2024
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
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 }}
tom2drum marked this conversation as resolved.
Show resolved Hide resolved
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
Loading