diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b46c7c..21c3247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### v4.3.0 + +- [feat] Integrated selected functionalities with Snowtrace.io +- [update] Set transaction explanation feature to be off by default +- [feat] Enabled support for decompilation via bytecode MD5 in Dedaub + ### v4.2.0 - [feat] Adaptation to Tronscan implemented diff --git a/README.md b/README.md index b2f5b62..d1c85d0 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ For up to the minute news, follow our [Twitter](https://twitter.com/MetaDockTeam ## Building -- Install [Node.js](https://nodejs.org) version 16 or later +- Install [Node.js](https://nodejs.org) version 18.12.0 or later - If you are using [nvm](https://github.com/nvm-sh/nvm#installing-and-updating) (recommended) running `nvm use` will automatically choose the right node version for you. - Install [Yarn](https://yarnpkg.com/en/docs/install) - Xcode (for building the Safari package) @@ -107,8 +107,6 @@ Whenever you change dependencies (adding, removing, or updating, either in `pack - [x] Show evm.storage shortcut - [x] Show transaction simulator - [x] Show Variable Logs -- [ ] Show token marketplaces -- [ ] Sandwich Attack Risk Detection ## Supported Websites List @@ -123,6 +121,7 @@ Whenever you change dependencies (adding, removing, or updating, either in `pack - snowtrace.io - optimistic.etherscan.io - opensea.io +- tronscan.org ## Changelog diff --git a/manifest.config.ts b/manifest.config.ts index 2620553..8d9871b 100644 --- a/manifest.config.ts +++ b/manifest.config.ts @@ -9,7 +9,7 @@ export default defineManifest((env: ConfigEnv) => { return { name: "MetaDock - Builders' Swiss Army Knife", description: - 'Improve the usability of blockchain explorers, including BTC.com, Etherscan, BscScan, and *scans of most EVM-compatible chains.', + 'Integrating 30+ popular Web3 and AI Tools, 300M+ Address Labels, and the Fund Flow Map into a single extension.', version: version, manifest_version: 3, icons: { @@ -27,7 +27,6 @@ export default defineManifest((env: ConfigEnv) => { '*://*.etherscan.com/*', '*://*.bscscan.com/*', '*://*.polygonscan.com/*', - '*://*.snowtrace.io/*', '*://optimistic.etherscan.io/*', '*://*.arbiscan.io/*', '*://*.ftmscan.com/*', @@ -49,7 +48,8 @@ export default defineManifest((env: ConfigEnv) => { ? [ '*://explorer.btc.com/*', '*://*.opensea.io/*', - '*://*.tronscan.org/*' + '*://*.tronscan.org/*', + '*://*.snowtrace.io/*' ] : [''], js: ['src/content/index.ts'], diff --git a/package.json b/package.json index acc17e3..ac2b827 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,13 @@ { "name": "metadock", - "version": "4.2.0", + "version": "4.3.0", "repository": { "type": "git", "url": "https://github.com/blocksecteam/metadock.git" }, + "engines": { + "node": ">=18.12.0" + }, "type": "module", "scripts": { "dev": "vite --mode development", diff --git a/src/background/index.ts b/src/background/index.ts index 1ae5bb7..9d84fff 100644 --- a/src/background/index.ts +++ b/src/background/index.ts @@ -7,10 +7,10 @@ import { EXECUTE_BTC_CONTENT_SCRIPT, GET_TOKEN_APPROVAL_DATATABLE, GET_TOKEN_APPROVAL_ERC20_FILTER, - EXECUTE_TRON_CONTENT_SCRIPT, TRONSCAN_TABS_CHANGED, LOAD_TRON_APPROVALS, - TRONSCAN_MULTI_SEARCH + TRONSCAN_MULTI_SEARCH, + URL_UPDATED } from '@common/constants' import { initBackgroundRequest } from './listeners' @@ -20,6 +20,15 @@ chromeEvent.on(REFRESH, () => { reloadCurrentTab() }) +/** url updated (spa) */ +browser.tabs.onUpdated.addListener(function (tabId, changeInfo) { + if (changeInfo.url) { + if (tabId) { + browser.tabs.sendMessage(tabId, URL_UPDATED).catch(() => void 0) + } + } +}) + /** reload BTC content script */ browser.webRequest.onCompleted.addListener( async details => { @@ -77,16 +86,6 @@ browser.webRequest.onCompleted.addListener( } ) -browser.tabs.onUpdated.addListener(function (tabId, changeInfo) { - if (changeInfo.url) { - if (tabId) { - browser.tabs - .sendMessage(tabId, EXECUTE_TRON_CONTENT_SCRIPT) - .catch(() => void 0) - } - } -}) - browser.webRequest.onCompleted.addListener( async details => { const { tabId, method } = details diff --git a/src/common/api/index.ts b/src/common/api/index.ts index 8ccc6c7..d66f07b 100644 --- a/src/common/api/index.ts +++ b/src/common/api/index.ts @@ -184,5 +184,11 @@ export default { .post('api/v1/variable/list', { json: params }) - .json>() + .json>(), + getSourceCodeMD5: (code: string) => + request + .post('api/v1/source-code/hash', { + json: { code } + }) + .json>() } diff --git a/src/common/components/CopyButton/index.tsx b/src/common/components/CopyButton/index.tsx index 15df483..c75e7d4 100644 --- a/src/common/components/CopyButton/index.tsx +++ b/src/common/components/CopyButton/index.tsx @@ -19,11 +19,9 @@ interface Props extends BaseComponent { mr?: number hover?: boolean placement?: 'left' | 'right' - theme?: string } const CopyButton: FC> = ({ - theme, text = '', size = 16, ml, @@ -86,12 +84,6 @@ const CopyButton: FC> = ({ isPureComponent ? style : {} ) - const _theme = theme - ? theme - : window.location.host.includes('etherscan') - ? 'var(--bs-primary)' - : 'var(--primary)' - const containerStyle: CSSProperties = Object.assign( { display: !isPureComponent ? 'inline-block' : 'contents' @@ -118,40 +110,38 @@ const CopyButton: FC> = ({ style={iconContainerStyle} > diff --git a/src/common/components/DrawerSimulation/index.tsx b/src/common/components/DrawerSimulation/index.tsx index 3b082ee..654b3ed 100644 --- a/src/common/components/DrawerSimulation/index.tsx +++ b/src/common/components/DrawerSimulation/index.tsx @@ -617,7 +617,6 @@ const DrawerSimulation: FC = ({ }} > form.getFieldValue([ 'parameters', @@ -631,7 +630,6 @@ const DrawerSimulation: FC = ({ } )} diff --git a/src/common/config/allowlist.ts b/src/common/config/allowlist.ts index 6bd34b2..949a540 100644 --- a/src/common/config/allowlist.ts +++ b/src/common/config/allowlist.ts @@ -1,7 +1,6 @@ export default { ETHERSCAN_V1_MATCHES: [ '*://zkevm.polygonscan.com/*', - '*://*.snowtrace.io/*', '*://optimistic.etherscan.io/*', '*://*.arbiscan.io/*', '*://testnet.ftmscan.com/*', @@ -35,5 +34,6 @@ export default { BTC_EXPLORER_MATCHES: ['*://explorer.btc.com/*'], BLOCKSEC_MATCHES: ['*://*.blocksec.com/*'], OPENSEA_MATCHES: ['*://*.opensea.io/*'], - TRONSCAN_MATCHES: ['*://*.tronscan.org/*'] + TRONSCAN_MATCHES: ['*://*.tronscan.org/*'], + SNOWTRACE_MATCHES: ['*://*.snowtrace.io/*'] } diff --git a/src/common/constants/event.ts b/src/common/constants/event.ts index af249ad..3839687 100644 --- a/src/common/constants/event.ts +++ b/src/common/constants/event.ts @@ -1,4 +1,5 @@ export const REFRESH = 'refresh' +export const URL_UPDATED = 'urlUpdated' export const GET_ADDRESS_RISK_SCORE = 'getAddressRiskScore' export const GET_ADDRESS_LABELS = 'getAddressLabels' export const GET_ADDRESS_METHODS = 'getAddressMethods' @@ -31,7 +32,6 @@ export const GET_LATEST_BLOCK = 'getLatestBlock' export const GET_CONTRACT_VARIABLE_LOGS = 'getContractVariableLogs' export const GET_CREATION_BLOCK = 'getCreationBlock' export const GET_CONTRACT_VARIABLE_LIST = 'getContractVariableList' -export const EXECUTE_TRON_CONTENT_SCRIPT = 'executeTronContentScript' export const LOAD_TRON_APPROVALS = 'loadTronApprovals' export const TRONSCAN_TABS_CHANGED = 'tronscanTabsChanged' export const TRONSCAN_MULTI_SEARCH = 'tronscanMultiSearch' diff --git a/src/common/constants/support.ts b/src/common/constants/support.ts index e85ce5a..a469386 100644 --- a/src/common/constants/support.ts +++ b/src/common/constants/support.ts @@ -161,17 +161,17 @@ export const EXT_SUPPORT_WEB_LIST: ExtSupportWebsite[] = [ chain: 'avalanche', domains: ['snowtrace.io'], siteName: 'ETHERSCAN', - logo: 'https://assets.blocksec.com/image/1671777583236-3.png', - testNets: [ - { - name: 'Avalanche Fuji', - chainID: 43_113, - chain: 'fuji.avalanche', - domains: ['testnet.snowtrace.io'], - siteName: 'ETHERSCAN', - logo: 'https://assets.blocksec.com/image/1671777583236-3.png' - } - ] + logo: 'https://assets.blocksec.com/image/1671777583236-3.png' + // testNets: [ + // { + // name: 'Avalanche Fuji', + // chainID: 43_113, + // chain: 'fuji.avalanche', + // domains: ['testnet.snowtrace.io'], + // siteName: 'ETHERSCAN', + // logo: 'https://assets.blocksec.com/image/1671777583236-3.png' + // } + // ] }, { name: 'Optimism', diff --git a/src/content/etherscan/components/DecompileInDedaubBtn/index.tsx b/src/content/etherscan/components/DecompileInDedaubBtn/index.tsx index 72f7d6c..bdc819c 100644 --- a/src/content/etherscan/components/DecompileInDedaubBtn/index.tsx +++ b/src/content/etherscan/components/DecompileInDedaubBtn/index.tsx @@ -1,7 +1,9 @@ -import { type FC } from 'react' +import { type FC, useState } from 'react' +import $ from 'jquery' import { DEDAUB_SUPPORT_DIRECT_LIST } from '@common/constants' import { getImageUrl } from '@common/utils' +import { LoadingOutlined } from '@common/components' import Button from '../Button' @@ -11,6 +13,8 @@ interface Props { } const DecompileInDedaubBtn: FC = ({ mainAddress, chain }) => { + const [loading, setLoading] = useState(false) + const toDedaub = () => { const item = DEDAUB_SUPPORT_DIRECT_LIST.find(item => item.chain === chain) @@ -20,14 +24,15 @@ const DecompileInDedaubBtn: FC = ({ mainAddress, chain }) => { ) } else { const url = 'https://library.dedaub.com/api/on_demand' - const bytecode = document.getElementById('dividcode') - if (bytecode == null) { + const bytecode = $('#dividcode').text().trim() + if (!bytecode) { window.open('https://library.dedaub.com/decompile') return } const data = { - hex_bytecode: bytecode.innerText + hex_bytecode: bytecode } + setLoading(true) fetch(url, { method: 'POST', headers: { @@ -41,15 +46,16 @@ const DecompileInDedaubBtn: FC = ({ mainAddress, chain }) => { }) .then(response => response.text()) .then(data => { - console.log('Success:', data) window.open( 'https://library.dedaub.com/decompile?md5=' + data.replace(/"/g, '') ) }) - .catch(error => { - console.error('Error:', error) + .catch(() => { window.open('https://library.dedaub.com/decompile') }) + .finally(() => { + setLoading(false) + }) } } @@ -58,7 +64,13 @@ const DecompileInDedaubBtn: FC = ({ mainAddress, chain }) => { style={{ width: 'fit-content' }} theme="#EFE6DA" fontColor="#000" - icon={} + icon={ + loading ? ( + + ) : ( + + ) + } onClick={toDedaub} > Decompile in Dedaub diff --git a/src/content/etherscan/components/ExplainBtn/index.tsx b/src/content/etherscan/components/ExplainBtn/index.tsx new file mode 100644 index 0000000..99a8261 --- /dev/null +++ b/src/content/etherscan/components/ExplainBtn/index.tsx @@ -0,0 +1,28 @@ +import { type FC, useState } from 'react' +import cls from 'classnames' + +import { TokenSymbol } from '@common/components' + +interface Props { + onClick: () => void +} + +const ExplainBtn: FC = ({ onClick }) => { + const [visible, setVisible] = useState(true) + + return ( + + ) +} + +export default ExplainBtn diff --git a/src/content/etherscan/components/TransactionExplanation/index.module.less b/src/content/etherscan/components/TransactionExplanation/index.module.less index e6c9229..52ed901 100644 --- a/src/content/etherscan/components/TransactionExplanation/index.module.less +++ b/src/content/etherscan/components/TransactionExplanation/index.module.less @@ -78,8 +78,8 @@ } } .btn { - width: 12px; - height: 12px; + width: 14px; + height: 14px; vertical-align: baseline; margin-right: 5px; .pointer; @@ -91,8 +91,8 @@ } .actionGroup { .btn { - width: 12px; - height: 12px; + width: 14px; + height: 14px; vertical-align: baseline; margin-right: 5px; .pointer; @@ -112,9 +112,9 @@ &:not(:first-of-type) { margin-top: 10px; } - img { - width: 16px; - height: 16px; + svg { + width: 14px; + height: 14px; margin-right: 10px; } } diff --git a/src/content/etherscan/components/TransactionExplanation/index.tsx b/src/content/etherscan/components/TransactionExplanation/index.tsx index ff44c22..bd3e39c 100644 --- a/src/content/etherscan/components/TransactionExplanation/index.tsx +++ b/src/content/etherscan/components/TransactionExplanation/index.tsx @@ -80,10 +80,19 @@ const TransactionExplanation: FC = props => { key: '1', label: (
setHidden(true)}> - + + + Hide for this transaction
) @@ -92,10 +101,19 @@ const TransactionExplanation: FC = props => { key: '2', label: (
- + + + Disable the feature
) @@ -127,11 +145,9 @@ const TransactionExplanation: FC = props => { return (