diff --git a/src/app/core/services/contract.service.ts b/src/app/core/services/contract.service.ts index c3bc393ed..ee39d30af 100644 --- a/src/app/core/services/contract.service.ts +++ b/src/app/core/services/contract.service.ts @@ -256,6 +256,27 @@ export class ContractService extends CommonService { .pipe(map((res) => (res?.data ? res?.data[this.envDB] : null))); } + findEvmContractList(listAddr: string[]) { + const operationsDoc = ` + query findEvmContractList($listAddress: [String!] = null) { + ${this.envDB} { + evm_smart_contract(where: {address: {_in: $listAddress}}, limit: 40, offset: 0) { + address + } + } + } + `; + return this.http + .post(this.graphUrl, { + query: operationsDoc, + variables: { + listAddress: listAddr.map(i=> i?.toLowerCase()) + }, + operationName: 'findEvmContractList', + }) + .pipe(map((res) => (res?.data ? res?.data[this.envDB] : null))); + } + loadContractDetail(contractAddress): Observable { const contractDoc = ` query queryContractDetail($contractAddress: String = null) { diff --git a/src/app/core/services/token.service.ts b/src/app/core/services/token.service.ts index 97de163fb..266c7c80a 100644 --- a/src/app/core/services/token.service.ts +++ b/src/app/core/services/token.service.ts @@ -569,10 +569,10 @@ export class TokenService extends CommonService { .post(this.graphUrl, { query: operationsDoc, variables: { - contractAddress: payload.contractAddr, + contractAddress: payload.contractAddr?.toLowerCase(), actionNotIn: queryActionNotIn, - sender: payload.sender, - receiver: payload.receiver, + sender: payload.sender?.toLowerCase(), + receiver: payload.receiver?.toLowerCase(), tokenId: payload.tokenId, idLte: payload.idLte, txHash: payload.txHash, diff --git a/src/app/pages/evm-contracts/evm-contracts.module.ts b/src/app/pages/evm-contracts/evm-contracts.module.ts index 0b3b433e9..c75ce699d 100644 --- a/src/app/pages/evm-contracts/evm-contracts.module.ts +++ b/src/app/pages/evm-contracts/evm-contracts.module.ts @@ -66,7 +66,7 @@ import { PopupProxyContractComponent } from './evm-proxy-contracts-verify/popup- ContractTableModule, NgbNavModule, ], - exports: [EvmReadComponent, EvmWriteComponent], + exports: [EvmReadComponent, EvmWriteComponent, EvmContractComponent], providers: [provideEnvironmentNgxMask(MASK_CONFIG)], }) export class EvmContractsModule {} diff --git a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-contract-tab/evm-token-contract-tab.component.html b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-contract-tab/evm-token-contract-tab.component.html index 9ea0e08b1..7daa65ce4 100644 --- a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-contract-tab/evm-token-contract-tab.component.html +++ b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-contract-tab/evm-token-contract-tab.component.html @@ -1,113 +1,7 @@
- - -
- -
- Are you the contract creator? - Verify and Publish - your contract source code today! -
-
-
- -
- In case this is proxy contract, verify - - Is this a proxy - - or not? -
-
- -
- - - -
- - -
- -
- - - - - - - - -
-
- ABI for the implementation contract at - - {{ implementationContractAddress }} - -
- -
- - - - - -
-
-
-
+
+ + +
diff --git a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-contract-tab/evm-token-contract-tab.component.ts b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-contract-tab/evm-token-contract-tab.component.ts index a52214ef6..d0abaf326 100644 --- a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-contract-tab/evm-token-contract-tab.component.ts +++ b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-contract-tab/evm-token-contract-tab.component.ts @@ -1,12 +1,16 @@ import { Component, Input, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { JsonFragment } from 'ethers'; import * as _ from 'lodash'; -import { of, switchMap } from 'rxjs'; +import { Subject, map, of, switchMap, takeUntil } from 'rxjs'; import { ContractVerifyType } from 'src/app/core/constants/contract.enum'; -import { TokenContractType } from 'src/app/core/constants/token.enum'; +import { ContractType } from 'src/app/core/constants/token.enum'; import { EnvironmentService } from 'src/app/core/data-services/environment.service'; import { ContractService } from 'src/app/core/services/contract.service'; import { getEthersProvider } from 'src/app/core/utils/ethers'; +import { EWalletType } from '../../../../../core/constants/wallet.constant'; +import local from '../../../../../core/utils/storage/local'; +import { STORAGE_KEYS } from '../../../../../core/constants/common.constant'; @Component({ selector: 'app-evm-token-contract-tab', @@ -15,12 +19,13 @@ import { getEthersProvider } from 'src/app/core/utils/ethers'; }) export class EvmTokenContractTabComponent implements OnInit { @Input() contractAddress: string; - @Input() typeContract: string; + @Input() contractTypeData: string; - contractType = TokenContractType; - currentTab = this.contractType.ReadContract; - contractVerifyType = ContractVerifyType; + ContractType = ContractType; + ContractVerifyType = ContractVerifyType; + currentTab = this.ContractType.ReadContract; isLoading = true; + isWatchList = false; contractDetail; contractCode; @@ -33,15 +38,58 @@ export class EvmTokenContractTabComponent implements OnInit { abi?: JsonFragment[]; }; + contract$ = this.route.paramMap.pipe( + map((data) => { + return data.get('contractAddress'); + }), + ); + destroyed$ = new Subject(); + constructor( + private route: ActivatedRoute, private contractService: ContractService, private env: EnvironmentService, - ) {} + ) { } ngOnInit(): void { - this.getContractDetail(); + this.contract$ + .pipe( + switchMap((ca) => { + if (!ca) { + return of(null); + } + this.contractAddress = ca; + return this.contractService.queryEvmContractByAddress(ca); + }), + takeUntil(this.destroyed$), + ) + .subscribe((res) => { + this.isLoading = false; + + if (res) { + const evm_contract_verification = _.get(res, 'evm_contract_verification[0]') || {}; + const evm_smart_contract = _.get(res, 'evm_smart_contract[0]') || {}; + + const contractDetail = { + ...evm_smart_contract, + ...evm_contract_verification, + }; + this.contractService.setContract(contractDetail); + } + }); + + this.contractService.contractObservable.pipe(takeUntil(this.destroyed$)).subscribe({ + next: (res) => { + this.contractDetail = { + ...res, + tx_hash: res.created_hash, + contract_hash: res.code_hash, + }; + }, + }); } + changeTab(tabId): void { this.currentTab = tabId; } @@ -62,75 +110,5 @@ export class EvmTokenContractTabComponent implements OnInit { }); } - getContractDetail() { - this.contractService.queryEvmContractByAddress(this.contractAddress).subscribe({ - next: (res) => { - if (res) { - const evm_contract_verification = _.get(res, 'evm_contract_verification[0]'); - const evm_smart_contract = _.get(res, 'evm_smart_contract[0]') || {}; - if (!evm_contract_verification) { - this.getContractCode(); - } else { - this.contractDetail = { - ...evm_smart_contract, - ...evm_contract_verification, - }; - - this.isLoading = false; - } - } - }, - error: () => { - this.isLoading = false; - }, - }); - } - - getProxyContractAbi(address) { - this.contractService - .getProxyContractAbi(address) - .pipe( - switchMap((e) => { - const proxyHistories = _.get(e, 'evm_smart_contract[0].evm_proxy_histories'); - - if (proxyHistories) { - this.implementationContractDetail = { - proxyContract: proxyHistories[0]?.proxy_contract, - implementationContract: proxyHistories[0]?.implementation_contract, - previouslyRecordedContract: proxyHistories[1]?.implementation_contract, - }; - - return this.contractService.queryEvmContractByAddress( - this.implementationContractDetail.implementationContract, - ); - } - - return of(null); - }), - ) - .subscribe((res) => { - const abi = _.get(res, 'evm_contract_verification[0].abi'); - if (abi) { - this.implementationContractDetail['abi'] = abi as JsonFragment[]; - } - }); - } - - loadProxyContractDetail() { - this.contractService.loadProxyContractDetail(this.contractAddress).subscribe((res) => { - if (res.implementation_contract) { - this.implementationContractAddress = res.implementation_contract; - this.getListContractInfo([res.implementation_contract]); - } - }); - } - - getListContractInfo(address) { - this.contractService.getListContractInfo(address).subscribe((res) => { - if (res?.evm_contract_verification?.length > 0) { - this.isImplementationVerified = res.evm_contract_verification[0]?.status; - } - }); - } } diff --git a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-transfers-tab/evm-token-transfers-tab.component.html b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-transfers-tab/evm-token-transfers-tab.component.html index df0c5c3f1..8ff1b8c3c 100644 --- a/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-transfers-tab/evm-token-transfers-tab.component.html +++ b/src/app/pages/evm-token/evm-token-content/evm-token-content-tab/evm-token-transfers-tab/evm-token-transfers-tab.component.html @@ -110,7 +110,7 @@ [value]="data[template.matColumnDef]" [linkRouter]="['/token', linkAddress]" [linkParams]="{ a: data[template.matColumnDef] }" - [iconContract]="data[template.matColumnDef] | isContract" + [iconContract]="isEvmSmartContract(data[template.matColumnDef])" [maxCharacter]="15"> @@ -139,7 +139,7 @@ { + let listAddr = [] + res.forEach((element) => { + if (element.from) { + listAddr.push(element.from) + } + if (element.to) { + listAddr.push(element.to) + } + }); + const listAddrUnique = _.uniq(listAddr); + return this.contractService.findEvmContractList(listAddrUnique).pipe( + map((r) => { + this.smartContractList = _.uniq((r?.evm_smart_contract || []).map(i => i?.address)); + return { listTokens: res } + }), + ); + } + ), ) .subscribe({ next: (res) => { if (res) { this.nextKey = null; - if (res?.length >= 100) { - this.nextKey = res[res.length - 1]['id']; + const listToken = res?.listTokens; + if (listToken?.length >= 100) { + this.nextKey = res[listToken.length - 1]['id']; this.hasMore.emit(true); } else { this.hasMore.emit(false); } - res.forEach((element) => { + listToken.forEach((element) => { element['tx_hash'] = element.evm_transaction.hash; element['from_address'] = element.from || NULL_ADDRESS; element['to_address'] = element.to || NULL_ADDRESS; @@ -211,13 +235,14 @@ export class EvmTokenTransfersTabComponent implements OnInit, AfterViewInit { }); if (this.dataSource.data.length > 0 && !isReload) { - this.dataSource.data = [...this.dataSource.data, ...res]; + this.dataSource.data = [...this.dataSource.data, ...listToken]; } else { - this.dataSource.data = [...res]; + this.dataSource.data = [...listToken]; } this.pageData.length = this.dataSource.data.length; this.tokenService.setTotalTransfer(this.pageData.length); + } }, error: (e) => { @@ -368,4 +393,8 @@ export class EvmTokenTransfersTabComponent implements OnInit, AfterViewInit { goTo(data) { this.router.navigate(['/token/evm/erc721', this.contractAddress, this.encodeData(data)]); } + + isEvmSmartContract(addr) { + return this.smartContractList.filter(i => i === addr).length > 0; + } } diff --git a/src/app/pages/evm-token/evm-token-content/evm-token-content.component.html b/src/app/pages/evm-token/evm-token-content/evm-token-content.component.html index d4cf28ac0..3f935c5c3 100644 --- a/src/app/pages/evm-token/evm-token-content/evm-token-content.component.html +++ b/src/app/pages/evm-token/evm-token-content/evm-token-content.component.html @@ -168,7 +168,7 @@ + [contractTypeData]="tokenDetail?.type"> diff --git a/src/app/pages/token/token-routing.module.ts b/src/app/pages/token/token-routing.module.ts index 7fd243cc8..31a51eb9a 100644 --- a/src/app/pages/token/token-routing.module.ts +++ b/src/app/pages/token/token-routing.module.ts @@ -29,7 +29,7 @@ const canMatchFn: CanMatchFn = (route, segments) => { return true; // Default, Show No Data screen } - const tr = router.createUrlTree(['/token', e.type.toLowerCase(), address.toLowerCase()], { + const tr = router.createUrlTree(['/token', e.type.toLowerCase(), address], { queryParams: currentQueryParams ? { ...currentQueryParams } : {}, }); @@ -44,7 +44,7 @@ const canMatchFn: CanMatchFn = (route, segments) => { return true; // Default, Show No Data screen } - const tr = router.createUrlTree(['/token', 'evm', e.type.toLowerCase(), address.toLowerCase()], { + const tr = router.createUrlTree(['/token', 'evm', e.type.toLowerCase(), address], { queryParams: currentQueryParams ? { ...currentQueryParams } : {}, });