From bb9b13668054a4ca2ff065767b3f82b4f2ead94f Mon Sep 17 00:00:00 2001 From: tamvb2391 <33695595+tamvb2391@users.noreply.github.com> Date: Mon, 15 Jul 2024 16:50:07 +0700 Subject: [PATCH] [featfix] add feature flag for enhance event log and token info (#3631) --- package.json | 2 +- scripts/feature-flags/dev/config.json | 2 +- scripts/feature-flags/euphoria/config.json | 2 +- scripts/feature-flags/mainnet/config.json | 2 +- scripts/feature-flags/serenity/config.json | 2 +- src/app/core/constants/feature-flags.enum.ts | 2 + .../evm-token-info-tab.component.html | 7 +- .../evm-token-info-tab.component.ts | 2 +- .../evm-token-content.component.ts | 18 ++- .../token-info-tab.component.html | 7 +- .../token-content/token-content.component.ts | 16 +- .../evm-message/evm-message.component.html | 10 ++ .../evm-message/evm-message.component.ts | 143 +++++++++++++----- .../evm-transaction-event-log.component.html | 38 +++-- .../evm-transaction-event-log.component.scss | 8 +- .../evm-transaction-event-log.component.ts | 16 +- 16 files changed, 203 insertions(+), 74 deletions(-) diff --git a/package.json b/package.json index c91c0176d..d49555cc5 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "start:dev": "ng serve", "build": "ng build --aot=true --output-hashing=all", "build:production": "ng build --aot=true --output-hashing=all --configuration production", - "featureflags": "node scripts/encryptFeatureFlags.mjs dev", + "featureflags": "node scripts/encryptFeatureFlags.mjs serenity", "watch": "ng build --watch --configuration development", "test": "ng test" }, diff --git a/scripts/feature-flags/dev/config.json b/scripts/feature-flags/dev/config.json index 839538bdd..72367d8c4 100644 --- a/scripts/feature-flags/dev/config.json +++ b/scripts/feature-flags/dev/config.json @@ -1 +1 @@ -{ "devTest": true } +{ "devTest": true, "enhanceEventLog": true, "setTokenInfo": true } diff --git a/scripts/feature-flags/euphoria/config.json b/scripts/feature-flags/euphoria/config.json index 67ceccfde..6eb07f737 100644 --- a/scripts/feature-flags/euphoria/config.json +++ b/scripts/feature-flags/euphoria/config.json @@ -1 +1 @@ -{ "devTest": false } +{ "devTest": false, "enhanceEventLog": false, "setTokenInfo": false } diff --git a/scripts/feature-flags/mainnet/config.json b/scripts/feature-flags/mainnet/config.json index 67ceccfde..6eb07f737 100644 --- a/scripts/feature-flags/mainnet/config.json +++ b/scripts/feature-flags/mainnet/config.json @@ -1 +1 @@ -{ "devTest": false } +{ "devTest": false, "enhanceEventLog": false, "setTokenInfo": false } diff --git a/scripts/feature-flags/serenity/config.json b/scripts/feature-flags/serenity/config.json index 67ceccfde..d64273c8c 100644 --- a/scripts/feature-flags/serenity/config.json +++ b/scripts/feature-flags/serenity/config.json @@ -1 +1 @@ -{ "devTest": false } +{ "devTest": false, "enhanceEventLog": true, "setTokenInfo": true } diff --git a/src/app/core/constants/feature-flags.enum.ts b/src/app/core/constants/feature-flags.enum.ts index b1acecb42..b51823941 100644 --- a/src/app/core/constants/feature-flags.enum.ts +++ b/src/app/core/constants/feature-flags.enum.ts @@ -4,4 +4,6 @@ const FEATURE_FLAGS_NAMESPACE = '32bf670d-a39e-46a7-8546-2a11d3c16b33'; export enum FeatureFlags { DevTest = uuidv5('devTest', FEATURE_FLAGS_NAMESPACE), + EnhanceEventLog = uuidv5('enhanceEventLog', FEATURE_FLAGS_NAMESPACE), + SetTokenInfo = uuidv5('setTokenInfo', FEATURE_FLAGS_NAMESPACE), } diff --git a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-info-tab/evm-token-info-tab.component.html b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-info-tab/evm-token-info-tab.component.html index a74a7cce9..f473b2cb4 100644 --- a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-info-tab/evm-token-info-tab.component.html +++ b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-info-tab/evm-token-info-tab.component.html @@ -1,4 +1,7 @@
OVERVIEW
-
-
\ No newline at end of file +
+ Aura gives you the joint benefits of open blockchain technology and traditional currency +
+
+ diff --git a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-info-tab/evm-token-info-tab.component.ts b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-info-tab/evm-token-info-tab.component.ts index fcb905701..838ededf9 100644 --- a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-info-tab/evm-token-info-tab.component.ts +++ b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-info-tab/evm-token-info-tab.component.ts @@ -1,4 +1,5 @@ import { Component, Input, OnInit } from '@angular/core'; +import { FeatureFlagService } from '../../../../../core/data-services/feature-flag.service'; @Component({ selector: 'app-evm-token-info-tab', @@ -10,4 +11,3 @@ export class EvmTokenInfoTabComponent implements OnInit { @Input() overviewInfo?: string; ngOnInit(): void {} } - diff --git a/src/app/pages/evm-token/evm-token-content/evm-token-content.component.ts b/src/app/pages/evm-token/evm-token-content/evm-token-content.component.ts index 1d45e0eca..1201db9ae 100644 --- a/src/app/pages/evm-token/evm-token-content/evm-token-content.component.ts +++ b/src/app/pages/evm-token/evm-token-content/evm-token-content.component.ts @@ -14,6 +14,8 @@ import { NameTagService } from 'src/app/core/services/name-tag.service'; import { TokenService } from 'src/app/core/services/token.service'; import { transferAddress } from 'src/app/core/utils/common/address-converter'; import local from 'src/app/core/utils/storage/local'; +import { FeatureFlagService } from '../../../core/data-services/feature-flag.service'; +import { FeatureFlags } from '../../../core/constants/feature-flags.enum'; @Component({ selector: 'app-evm-token-content', @@ -65,6 +67,7 @@ export class EvmTokenContentComponent implements OnInit { private nameTagService: NameTagService, private router: Router, private beautyAddress: EvmAddressPipe, + private featureFlag: FeatureFlagService, ) {} ngOnInit(): void { @@ -108,12 +111,14 @@ export class EvmTokenContentComponent implements OnInit { this.searchTemp = this.nameTagService.findNameTagByAddress(this.searchTemp); } - if (!this.paramQuery) { - this.TABS.push({ - key: TokenTab.Info, - value: 'Info', - }); - this.tabsBackup = this.TABS; + if (this.featureFlag.isEnabled(FeatureFlags.SetTokenInfo)) { + if (!this.paramQuery) { + this.TABS.push({ + key: TokenTab.Info, + value: 'Info', + }); + this.tabsBackup = this.TABS; + } } }); @@ -239,4 +244,3 @@ export class EvmTokenContentComponent implements OnInit { .toFixed(); } } - diff --git a/src/app/pages/token-cosmos/token-content/token-content-tab/token-info-tab/token-info-tab.component.html b/src/app/pages/token-cosmos/token-content/token-content-tab/token-info-tab/token-info-tab.component.html index a74a7cce9..f473b2cb4 100644 --- a/src/app/pages/token-cosmos/token-content/token-content-tab/token-info-tab/token-info-tab.component.html +++ b/src/app/pages/token-cosmos/token-content/token-content-tab/token-info-tab/token-info-tab.component.html @@ -1,4 +1,7 @@
OVERVIEW
-
-
\ No newline at end of file +
+ Aura gives you the joint benefits of open blockchain technology and traditional currency +
+
+ diff --git a/src/app/pages/token-cosmos/token-content/token-content.component.ts b/src/app/pages/token-cosmos/token-content/token-content.component.ts index 38a72fa61..ec22e09a7 100644 --- a/src/app/pages/token-cosmos/token-content/token-content.component.ts +++ b/src/app/pages/token-cosmos/token-content/token-content.component.ts @@ -14,6 +14,8 @@ import { NameTagService } from 'src/app/core/services/name-tag.service'; import { TokenService } from 'src/app/core/services/token.service'; import { transferAddress } from 'src/app/core/utils/common/address-converter'; import local from 'src/app/core/utils/storage/local'; +import { FeatureFlagService } from '../../../core/data-services/feature-flag.service'; +import { FeatureFlags } from '../../../core/constants/feature-flags.enum'; @Component({ selector: 'app-token-content', @@ -26,9 +28,9 @@ export class TokenContentComponent implements OnInit { @Input() channelPath: any; @Output() hasMore = new EventEmitter(); - tabStaking = [TokenTab.Holders, TokenTab.Info]; - tabIBC = [TokenTab.Transfers, TokenTab.Holders, TokenTab.Info]; - tabToken = [TokenTab.Transfers, TokenTab.Holders, TokenTab.Contract, TokenTab.Info]; + tabStaking = [TokenTab.Holders]; + tabIBC = [TokenTab.Transfers, TokenTab.Holders]; + tabToken = [TokenTab.Transfers, TokenTab.Holders, TokenTab.Contract]; tabNFT = [TokenTab.Transfers, TokenTab.Holders, TokenTab.Inventory, TokenTab.Contract]; TABS = []; paramQuery = ''; @@ -67,9 +69,16 @@ export class TokenContentComponent implements OnInit { private nameTagService: NameTagService, private contractService: ContractService, private router: Router, + private featureFlag: FeatureFlagService, ) {} ngOnInit(): void { + if (this.featureFlag.isEnabled(FeatureFlags.SetTokenInfo)) { + this.tabStaking = [TokenTab.Holders, TokenTab.Info]; + this.tabIBC = [TokenTab.Transfers, TokenTab.Holders, TokenTab.Info]; + this.tabToken = [TokenTab.Transfers, TokenTab.Holders, TokenTab.Contract, TokenTab.Info]; + } + this.linkAddress = this.route.snapshot.paramMap.get('contractAddress'); let tabFilter; switch (this.tokenDetail.modeToken) { @@ -254,4 +263,3 @@ export class TokenContentComponent implements OnInit { .toFixed(); } } - diff --git a/src/app/pages/transaction/evm-transaction/evm-message/evm-message.component.html b/src/app/pages/transaction/evm-transaction/evm-message/evm-message.component.html index 671edacd5..d3022c37f 100644 --- a/src/app/pages/transaction/evm-transaction/evm-message/evm-message.component.html +++ b/src/app/pages/transaction/evm-transaction/evm-message/evm-message.component.html @@ -134,6 +134,16 @@
Transaction Receipt Event Logs ({{ eventLog?.length }})
+ + + { + this.contractAddressAbi = + _.get(res, 'evm_smart_contract[0].evm_proxy_histories[0].implementation_contract') || this.contractAddressAbi; + }, + complete: () => { + this.getDataDecoded(); + }, + }); + } + + getDataDecoded() { + if (!this.contractAddressAbi) { + return; + } + + this.transactionService.getAbiContract(this.contractAddressAbi?.toLowerCase()).subscribe((res) => { + if (res?.evm_contract_verification?.length > 0 && res.evm_contract_verification[0]?.abi) { + this.isContractVerified = true; + this.isDecoded = true; + this.interfaceCoder = new Interface(res.evm_contract_verification[0].abi); + + const value = parseEther('1.0'); + const rawData = this.interfaceCoder.parseTransaction({ data: '0x' + this.transaction?.inputData, value }); + if (rawData?.fragment?.inputs?.length > 0) { + this.getListTopicDecodeOld(); + this.inputDataRaw['name'] = + this.interfaceCoder.getFunction(rawData?.fragment?.name)?.format() || rawData.name; + this.inputDataDecoded['name'] = rawData.name; + this.inputDataDecoded['params'] = rawData?.fragment?.inputs.map((item, index) => { + return { + name: item.name, + type: item.type, + value: rawData.args[index], + }; + }); + } + } + }); + } + getProxyContractAbi() { let listContract = this.transaction.eventLog.map((i) => i.address?.toLowerCase()); listContract.push(this.transaction?.to?.toLowerCase()); @@ -98,9 +149,8 @@ export class EvmMessageComponent { return; } const implementationContractList = this.contractAddressAbiList.map((i) => i.implementation_contract); - + this.transactionService.getListAbiContract(implementationContractList).subscribe((res) => { - if (res?.evm_contract_verification?.length > 0) { this.isDecoded = true; this.abiContractData = res?.evm_contract_verification.map((i) => ({ @@ -112,16 +162,15 @@ export class EvmMessageComponent { })); const abiInfo = this.abiContractData.find((f) => f.contractAddress === this.transaction?.to); - + if (abiInfo) { this.isContractVerified = true; const value = parseEther('1.0'); const rawData = abiInfo.interfaceCoder.parseTransaction({ data: '0x' + this.transaction?.inputData, value }); - - this.inputDataRaw['name'] = - abiInfo.interfaceCoder.getFunction(rawData?.selector)?.format() || rawData.name; + + this.inputDataRaw['name'] = abiInfo.interfaceCoder.getFunction(rawData?.selector)?.format() || rawData.name; this.inputDataDecoded['name'] = rawData.name; - + if (rawData?.fragment?.inputs?.length > 0) { this.inputDataDecoded['params'] = rawData?.fragment?.inputs.map((item, index) => { return { @@ -137,7 +186,7 @@ export class EvmMessageComponent { }); } - mappingTopics(element){ + mappingTopics(element) { element['isAllowSwitchDecodeDataField'] = false; return element?.topics?.map((i, tidx) => ({ index: tidx, @@ -147,17 +196,32 @@ export class EvmMessageComponent { })); } - mappingFunctionName(item){ - const {type, indexed, name} = item; + mappingFunctionName(item) { + const { type, indexed, name } = item; let param = type; - if (!indexed) param = `${type} ${name}` - else param = `${type} indexed ${name}` + if (!indexed) param = `${type} ${name}`; + else param = `${type} indexed ${name}`; return param; } + getListTopicDecodeOld() { + this.transaction.eventLog.forEach((element, index) => { + let arrTopicTemp = element?.evm_signature_mapping_topic || []; + try { + const arrTemp = + this.interfaceCoder + .decodeEventLog(element.topic0, `0x${this.transaction?.inputData}`, element.topics) + .toArray() || []; + arrTopicTemp = [...this.arrTopicDecode[index], ...arrTemp]; + } catch (e) {} + + this.arrTopicDecode[index] = arrTopicTemp; + }); + this.arrTopicDecode = [...this.arrTopicDecode]; + } + getListTopicDecode() { this.transaction.eventLog.forEach((element, index) => { - let arrTopicTemp = element?.evm_signature_mapping_topic || []; try { const abiInfo = this.abiContractData.find((f) => f.contractAddress === element.address); @@ -166,18 +230,18 @@ export class EvmMessageComponent { element['isAllowSwitchDecodeDataField'] = true; if (!abiInfo?.abi) { - decoded = this.mappingTopics(element) + decoded = this.mappingTopics(element); } else { const paramsDecode = abiInfo.interfaceCoder.parseLog({ topics: element.topics?.filter((f) => f), data: `0x${element.data || this.transaction?.inputData}`, }); - if(!paramsDecode) decoded = this.mappingTopics(element) + if (!paramsDecode) decoded = this.mappingTopics(element); else { const params = paramsDecode?.fragment?.inputs.map(this.mappingFunctionName); const decodeTopic0 = `> ${paramsDecode?.fragment?.name}(${params.join(', ')})`; - + decoded = [ { index: 0, @@ -185,44 +249,44 @@ export class EvmMessageComponent { value: element.topics[0], }, ]; - - const inputs = paramsDecode?.fragment?.inputs + + const inputs = paramsDecode?.fragment?.inputs; if (inputs?.length > 0) { const params = []; const data = []; let currentParamIndex = 0; - + inputs?.forEach((item, idx) => { - if(item?.type === "tuple") { + if (item?.type === 'tuple') { const tupleType = `(${item?.components?.map(this.mappingFunctionName)?.join(', ')}) ${item?.name}`; const replaceTuple = new RegExp(`\\b${item?.type} ${item?.name}\\b`, 'g'); decoded[0].decode = decoded[0]?.decode?.replace(replaceTuple, tupleType); - } - + } + const param = { indexed: item?.indexed, name: item.name, type: item.type, isLink: item.type === 'address', decode: paramsDecode.args[idx]?.toString(), - } - if(item?.indexed) { - param["indexed"] = item.indexed; - param["index"] = currentParamIndex + 1; - param["isAllowSwitchDecode"] = true; - param["value"] = element.topics[currentParamIndex + 1], - currentParamIndex += 1; + }; + if (item?.indexed) { + param['indexed'] = item.indexed; + param['index'] = currentParamIndex + 1; + param['isAllowSwitchDecode'] = true; + (param['value'] = element.topics[currentParamIndex + 1]), (currentParamIndex += 1); params.push(param); - }else { + } else { data.push(param); } }); - + element.dataDecoded = data; decoded = [...decoded, ...params]; - }} + } + } } - + this.topicsDecoded[index] = decoded; } catch (e) {} this.arrTopicDecode[index] = arrTopicTemp; @@ -233,9 +297,8 @@ export class EvmMessageComponent { getMethodName(methodId) { this.transactionService.getListMappingName(methodId).subscribe((res) => { this.method = mappingMethodName(res, methodId); - if(!this.isEvmContract) this.method = 'Send'; - if(!this.transaction?.to) this.method = 'Create Contract'; - + if (!this.isEvmContract) this.method = 'Send'; + if (!this.transaction?.to) this.method = 'Create Contract'; }); } } diff --git a/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.html b/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.html index b3c27b216..7d438f685 100644 --- a/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.html +++ b/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.html @@ -17,11 +17,29 @@
-
- Topics -
+
Topics
- + +
+
{{ idx }}
+
+
+ {{ top }} +
+
+
+
+
+
-
- Data -
+
Data
+
+ {{ eventLog.data }} +
-
\ No newline at end of file + diff --git a/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.scss b/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.scss index 75042e6d7..1f64b1534 100644 --- a/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.scss +++ b/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.scss @@ -48,7 +48,11 @@ max-width: calc(100% - 38px); } - .event-log-msg { - color: var(--aura-gray-3); + .highlight { + width: max-content; + max-width: 98%; + padding: 4px 8px; + border-radius: 4px; + background-color: var(--aura-gray-10); } } diff --git a/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.ts b/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.ts index b5f08a53e..f1dda3db5 100644 --- a/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.ts +++ b/src/app/pages/transaction/evm-transaction/evm-transaction-event-log/evm-transaction-event-log.component.ts @@ -1,4 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { FeatureFlagService } from '../../../../core/data-services/feature-flag.service'; +import { FeatureFlags } from '../../../../core/constants/feature-flags.enum'; @Component({ selector: 'app-evm-transaction-event-log', @@ -6,7 +8,7 @@ import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleCha styleUrls: ['./evm-transaction-event-log.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class EvmTransactionEventLogComponent { +export class EvmTransactionEventLogComponent implements OnInit { @Input() arrTopicDecode; @Input() topicsDecoded; @Input() eventLog: { @@ -19,7 +21,17 @@ export class EvmTransactionEventLogComponent { }[]; data: string; dataDecoded?: string; - isAllowSwitchDecodeDataField ?:boolean + isAllowSwitchDecodeDataField?: boolean; }; @Input() index; + + constructor(private featureFlag: FeatureFlagService) {} + + ngOnInit(): void { + if (!this.featureFlag.isEnabled(FeatureFlags.EnhanceEventLog)) { + if (this.eventLog?.data) { + this.eventLog['data'] = this.eventLog?.data.replace('\\x', ''); + } + } + } }