Skip to content

Commit 1045130

Browse files
committed
refactor: Centralize SolidityScan logic into a shared helper
1 parent 3a6ccc3 commit 1045130

File tree

10 files changed

+108
-276
lines changed

10 files changed

+108
-276
lines changed

libs/remix-ui/helper/src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ export * from './lib/components/PluginViewWrapper'
55
export * from './lib/components/custom-dropdown'
66
export * from './lib/components/custom-tooltip'
77
export * from './lib/components/feedback'
8-
export type { CompilerReport } from './types/compilerTypes'
8+
export * from './lib/components/solScanTable'
9+
export * from './lib/solidity-scan'
10+
export type { CompilerReport } from './types/compilerTypes'
11+
export * from './types/solidity-scan'

libs/remix-ui/solidity-compiler/src/lib/solScanTable.tsx renamed to libs/remix-ui/helper/src/lib/components/solScanTable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// eslint-disable-next-line no-use-before-define
22
import React from 'react'
33
import parse from 'html-react-parser'
4-
import { ScanReport } from './types'
4+
import { ScanReport } from '@remix-ui/helper'
55
const _paq = (window._paq = window._paq || [])
66

77
interface SolScanTableProps {
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// remix-project/libs/remix-ui/helper/src/lib/solidity-scan.tsx
2+
3+
import React from 'react'
4+
import axios from 'axios'
5+
import { FormattedMessage } from 'react-intl'
6+
import { endpointUrls } from '@remix-endpoints-helper'
7+
import { ScanReport, SolScanTable } from '@remix-ui/helper'
8+
9+
const _paq = (window._paq = window._paq || [])
10+
11+
export const handleSolidityScan = async (api: any, compiledFileName: string) => {
12+
await api.call('notification', 'toast', 'Processing data to scan...')
13+
_paq.push(['trackEvent', 'solidityCompiler', 'solidityScan', 'initiateScan'])
14+
15+
const workspace = await api.call('filePanel', 'getCurrentWorkspace')
16+
const fileName = `${workspace.name}/${compiledFileName}`
17+
const filePath = `.workspaces/${fileName}`
18+
const file = await api.call('fileManager', 'readFile', filePath)
19+
20+
try {
21+
const urlResponse = await axios.post(`${endpointUrls.solidityScan}/uploadFile`, { file, fileName })
22+
23+
if (urlResponse.data.status === 'success') {
24+
const ws = new WebSocket(`${endpointUrls.solidityScanWebSocket}/solidityscan`)
25+
ws.addEventListener('error', console.error)
26+
27+
ws.addEventListener('open', async () => {
28+
await api.call('notification', 'toast', 'Loading scan result in Remix terminal...')
29+
})
30+
31+
ws.addEventListener('message', async (event) => {
32+
const data = JSON.parse(event.data)
33+
if (data.type === "auth_token_register" && data.payload.message === "Auth token registered.") {
34+
ws.send(JSON.stringify({
35+
action: "message",
36+
payload: {
37+
type: "private_project_scan_initiate",
38+
body: {
39+
file_urls: [urlResponse.data.result.url],
40+
project_name: "RemixProject",
41+
project_type: "new"
42+
}
43+
}
44+
}))
45+
} else if (data.type === "scan_status" && data.payload.scan_status === "download_failed") {
46+
_paq.push(['trackEvent', 'solidityCompiler', 'solidityScan', 'scanFailed'])
47+
await api.call('notification', 'modal', {
48+
id: 'SolidityScanError',
49+
title: <FormattedMessage id="solidity.solScan.errModalTitle" />,
50+
message: data.payload.scan_status_err_message,
51+
okLabel: 'Close'
52+
})
53+
ws.close()
54+
} else if (data.type === "scan_status" && data.payload.scan_status === "scan_done") {
55+
_paq.push(['trackEvent', 'solidityCompiler', 'solidityScan', 'scanSuccess'])
56+
const { data: scanData } = await axios.post(`${endpointUrls.solidityScan}/downloadResult`, { url: data.payload.scan_details.link })
57+
const scanReport: ScanReport = scanData.scan_report
58+
59+
if (scanReport?.multi_file_scan_details?.length) {
60+
for (const template of scanReport.multi_file_scan_details) {
61+
if (template.metric_wise_aggregated_findings?.length) {
62+
const positions = []
63+
for (const details of template.metric_wise_aggregated_findings) {
64+
for (const f of details.findings)
65+
positions.push(`${f.line_nos_start[0]}:${f.line_nos_end[0]}`)
66+
}
67+
template.positions = JSON.stringify(positions)
68+
}
69+
}
70+
await api.call('terminal', 'logHtml', <SolScanTable scanReport={scanReport} fileName={fileName}/>)
71+
} else {
72+
await api.call('notification', 'modal', {
73+
id: 'SolidityScanError',
74+
title: <FormattedMessage id="solidity.solScan.errModalTitle" />,
75+
message: "Some error occurred! Please try again",
76+
okLabel: 'Close'
77+
})
78+
}
79+
ws.close()
80+
}
81+
})
82+
} else {
83+
await api.call('notification', 'toast', 'Error in processing data to scan')
84+
console.error(urlResponse.data && urlResponse.data.error ? urlResponse.data.error : urlResponse)
85+
}
86+
} catch (error) {
87+
await api.call('notification', 'toast', 'Error in processing data to scan. Please check the console for details.')
88+
console.error(error)
89+
}
90+
}

libs/remix-ui/tabs/src/lib/types/index.ts renamed to libs/remix-ui/helper/src/types/solidity-scan.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//// SolidityScan Types
2-
31
export interface ScanTemplate {
42
issue_id: string
53
issue_name: string
@@ -29,5 +27,4 @@ export interface ScanReport {
2927
scan_id: string
3028
scan_status: string
3129
scan_type: string
32-
// others
33-
}
30+
}

libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx

Lines changed: 3 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import React, {useState, useEffect} from 'react' // eslint-disable-line
22
import { FormattedMessage, useIntl } from 'react-intl'
3-
import { ContractPropertyName, ContractSelectionProps, ScanReport } from './types'
3+
import { ContractPropertyName, ContractSelectionProps } from './types'
44
import {PublishToStorage} from '@remix-ui/publish-to-storage' // eslint-disable-line
55
import {TreeView, TreeViewItem} from '@remix-ui/tree-view' // eslint-disable-line
66
import {CopyToClipboard} from '@remix-ui/clipboard' // eslint-disable-line
77
import { saveAs } from 'file-saver'
88
import { AppModal } from '@remix-ui/app'
9-
import { SolScanTable } from './solScanTable'
10-
import axios from 'axios'
119

1210
import './css/style.css'
13-
import { CustomTooltip } from '@remix-ui/helper'
14-
import { endpointUrls } from '@remix-endpoints-helper'
11+
import { CustomTooltip, handleSolidityScan } from '@remix-ui/helper'
1512

1613
const _paq = (window._paq = window._paq || [])
1714

@@ -261,91 +258,7 @@ export const ContractSelection = (props: ContractSelectionProps) => {
261258
}
262259

263260
const handleScanContinue = async () => {
264-
const plugin = api as any
265-
await plugin.call('notification', 'toast', 'Processing data to scan...')
266-
_paq.push(['trackEvent', 'solidityCompiler', 'solidityScan', 'initiateScan'])
267-
const workspace = await plugin.call('filePanel', 'getCurrentWorkspace')
268-
const fileName = `${workspace.name}/${props.compiledFileName}`
269-
const filePath = `.workspaces/${fileName}`
270-
const file = await plugin.call('fileManager', 'readFile', filePath)
271-
272-
const urlResponse = await axios.post(`${endpointUrls.solidityScan}/uploadFile`, { file, fileName })
273-
274-
if (urlResponse.data.status === 'success') {
275-
const ws = new WebSocket(`${endpointUrls.solidityScanWebSocket}/solidityscan`)
276-
277-
ws.addEventListener('error', console.error);
278-
279-
ws.addEventListener('open', async (event) => {
280-
await plugin.call('notification', 'toast', 'Loading scan result in Remix terminal...')
281-
})
282-
283-
ws.addEventListener('message', async (event) => {
284-
const data = JSON.parse(event.data)
285-
if (data.type === "auth_token_register" && data.payload.message === "Auth token registered.") {
286-
// Message on Bearer token successful registration
287-
const reqToInitScan = {
288-
"action": "message",
289-
"payload": {
290-
"type": "private_project_scan_initiate",
291-
"body": {
292-
"file_urls": [
293-
urlResponse.data.result.url
294-
],
295-
"project_name": "RemixProject",
296-
"project_type": "new"
297-
}
298-
}
299-
}
300-
ws.send(JSON.stringify(reqToInitScan))
301-
} else if (data.type === "scan_status" && data.payload.scan_status === "download_failed") {
302-
// Message on failed scan
303-
_paq.push(['trackEvent', 'solidityCompiler', 'solidityScan', 'scanFailed'])
304-
const modal: AppModal = {
305-
id: 'SolidityScanError',
306-
title: <FormattedMessage id="solidity.solScan.errModalTitle" />,
307-
message: data.payload.scan_status_err_message,
308-
okLabel: 'Close'
309-
}
310-
await plugin.call('notification', 'modal', modal)
311-
ws.close()
312-
} else if (data.type === "scan_status" && data.payload.scan_status === "scan_done") {
313-
// Message on successful scan
314-
_paq.push(['trackEvent', 'solidityCompiler', 'solidityScan', 'scanSuccess'])
315-
const url = data.payload.scan_details.link
316-
317-
const { data: scanData } = await axios.post(`${endpointUrls.solidityScan}/downloadResult`, { url })
318-
const scanReport: ScanReport = scanData.scan_report
319-
if (scanReport?.multi_file_scan_details?.length) {
320-
for (const template of scanReport.multi_file_scan_details) {
321-
if (template.metric_wise_aggregated_findings?.length) {
322-
const { metric_wise_aggregated_findings } = template
323-
const positions = []
324-
for (const details of metric_wise_aggregated_findings) {
325-
const { findings } = details
326-
for (const f of findings)
327-
positions.push(`${f.line_nos_start[0]}:${f.line_nos_end[0]}`)
328-
}
329-
template.positions = JSON.stringify(positions)
330-
}
331-
}
332-
await plugin.call('terminal', 'logHtml', <SolScanTable scanReport={scanReport} fileName={fileName}/>)
333-
} else {
334-
const modal: AppModal = {
335-
id: 'SolidityScanError',
336-
title: <FormattedMessage id="solidity.solScan.errModalTitle" />,
337-
message: "Some error occurred! Please try again",
338-
okLabel: 'Close'
339-
}
340-
await plugin.call('notification', 'modal', modal)
341-
}
342-
ws.close()
343-
}
344-
})
345-
} else {
346-
await plugin.call('notification', 'toast', 'Error in processing data to scan')
347-
console.error(urlResponse.data && urlResponse.data.error ? urlResponse.data.error : urlResponse)
348-
}
261+
await handleSolidityScan(api, props.compiledFileName)
349262
}
350263

351264
const runSolidityScan = async () => {

libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import * as packageJson from '../../../../../package.json'
1010
import './css/style.css'
1111
import { iSolJsonBinData, iSolJsonBinDataBuild } from '@remix-project/remix-lib'
1212
import { appPlatformTypes, platformContext } from '@remix-ui/app'
13-
import { CompileDropdown } from '../../../tabs/src/lib/components/CompileDropdown'
1413

1514
export const SolidityCompiler = (props: SolidityCompilerProps) => {
1615
const {

libs/remix-ui/solidity-compiler/src/lib/types/index.ts

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,6 @@ export type onCurrentFileChanged = (fileName: string) => void
44

55
//// SolidityScan Types
66

7-
export interface ScanTemplate {
8-
issue_id: string
9-
issue_name: string
10-
issue_remediation?: string
11-
issue_severity: string
12-
issue_status: string
13-
static_issue_description: string
14-
issue_description?: string
15-
issue_confidence: string
16-
metric_wise_aggregated_findings?: Record<string, any>[]
17-
}
18-
19-
export interface ScanDetails {
20-
issue_id: string
21-
no_of_findings: string
22-
metric_wise_aggregated_findings?: Record<string, any>[]
23-
positions?: string
24-
template_details: ScanTemplate
25-
}
26-
27-
export interface ScanReport {
28-
details_enabled: boolean
29-
file_url_list: string[]
30-
multi_file_scan_details: ScanDetails[]
31-
multi_file_scan_summary: Record<string, any>
32-
multi_file_scan_status: string
33-
scan_id: string
34-
scan_status: string
35-
scan_type: string
36-
// others
37-
}
38-
39-
//// SolidityScan Types
40-
417
export interface SolidityCompilerProps {
428
api: ICompilerApi
439
}

libs/remix-ui/tabs/src/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
export * from './lib/remix-ui-tabs'
2-
export * from './lib/types'
32
export { CompileDropdown } from './lib/components/CompileDropdown'
43
export { default as RunScriptDropdown } from './lib/components/RunScriptDropdown'
54
export { default as Dropdown } from './lib/components/DropdownMenu'
6-
export { SolScanTable } from './lib/components/solScanTable'
75

86
export { default as AnalysisLogo } from './assets/icons/Analysis'
97
export { default as ArrowRightBig } from './assets/icons/ArrowRightBig'

libs/remix-ui/tabs/src/lib/components/CompileDropdown.tsx

Lines changed: 9 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ import React, { useState, useEffect } from 'react'
22
import DropdownMenu, { MenuItem } from './DropdownMenu'
33
import { AppModal } from '@remix-ui/app'
44
import { FormattedMessage } from 'react-intl'
5-
import { SolScanTable, ScanReport } from '@remix-ui/tabs'
6-
import axios from 'axios'
7-
import { endpointUrls } from '@remix-endpoints-helper'
5+
import { handleSolidityScan } from '@remix-ui/helper'
86

97
import { ArrowRightBig, IpfsLogo, SwarmLogo, SettingsLogo, SolidityScanLogo, AnalysisLogo, TsLogo } from '@remix-ui/tabs'
108

@@ -59,79 +57,14 @@ export const CompileDropdown: React.FC<CompileDropdownProps> = ({ tabPath, plugi
5957

6058
const handleScanContinue = async () => {
6159
await plugin.call('solidity', 'compile', tabPath)
62-
await plugin.call('notification', 'toast', 'Processing data to scan...')
63-
_paq.push(['trackEvent', 'solidityCompiler', 'solidityScan', 'initiateScan'])
64-
65-
const workspace = await plugin.call('filePanel', 'getCurrentWorkspace')
66-
const fileName = `${workspace.name}/${compiledFileName}`
67-
const filePath = `.workspaces/${compiledFileName}`
68-
const file = await plugin.call('fileManager', 'readFile', filePath)
69-
70-
const urlResponse = await axios.post(`${endpointUrls.solidityScan}/uploadFile`, { file, fileName })
71-
72-
if (urlResponse.data.status === 'success') {
73-
const ws = new WebSocket(`${endpointUrls.solidityScanWebSocket}/solidityscan`)
74-
ws.addEventListener('error', console.error)
75-
76-
ws.addEventListener('open', async () => {
77-
await plugin.call('notification', 'toast', 'Loading scan result in Remix terminal...')
78-
})
79-
80-
ws.addEventListener('message', async (event) => {
81-
const data = JSON.parse(event.data)
82-
if (data.type === "auth_token_register" && data.payload.message === "Auth token registered.") {
83-
ws.send(JSON.stringify({
84-
action: "message",
85-
payload: {
86-
type: "private_project_scan_initiate",
87-
body: {
88-
file_urls: [urlResponse.data.result.url],
89-
project_name: "RemixProject",
90-
project_type: "new"
91-
}
92-
}
93-
}))
94-
} else if (data.type === "scan_status" && data.payload.scan_status === "download_failed") {
95-
_paq.push(['trackEvent', 'solidityCompiler', 'solidityScan', 'scanFailed'])
96-
await plugin.call('notification', 'modal', {
97-
id: 'SolidityScanError',
98-
title: <FormattedMessage id="solidity.solScan.errModalTitle" />,
99-
message: data.payload.scan_status_err_message,
100-
okLabel: 'Close'
101-
})
102-
ws.close()
103-
} else if (data.type === "scan_status" && data.payload.scan_status === "scan_done") {
104-
_paq.push(['trackEvent', 'solidityCompiler', 'solidityScan', 'scanSuccess'])
105-
const { data: scanData } = await axios.post(`${endpointUrls.solidityScan}/downloadResult`, { url: data.payload.scan_details.link })
106-
const scanReport: ScanReport = scanData.scan_report
107-
108-
if (scanReport?.multi_file_scan_details?.length) {
109-
for (const template of scanReport.multi_file_scan_details) {
110-
if (template.metric_wise_aggregated_findings?.length) {
111-
const positions = []
112-
for (const details of template.metric_wise_aggregated_findings) {
113-
for (const f of details.findings)
114-
positions.push(`${f.line_nos_start[0]}:${f.line_nos_end[0]}`)
115-
}
116-
template.positions = JSON.stringify(positions)
117-
}
118-
}
119-
await plugin.call('terminal', 'logHtml', <SolScanTable scanReport={scanReport} fileName={fileName}/>)
120-
} else {
121-
await plugin.call('notification', 'modal', {
122-
id: 'SolidityScanError',
123-
title: <FormattedMessage id="solidity.solScan.errModalTitle" />,
124-
message: "Some error occurred! Please try again",
125-
okLabel: 'Close'
126-
})
127-
}
128-
ws.close()
129-
}
130-
})
131-
} else {
132-
await plugin.call('notification', 'toast', 'Error in processing data to scan')
133-
console.error(urlResponse.data && urlResponse.data.error ? urlResponse.data.error : urlResponse)
134-
}
60+
61+
const firstSlashIndex = compiledFileName.indexOf('/');
62+
63+
const finalPath = firstSlashIndex > 0
64+
? compiledFileName.substring(firstSlashIndex + 1)
65+
: compiledFileName;
66+
67+
await handleSolidityScan(plugin, finalPath)
13568
}
13669

13770
const runSolidityScan = async () => {

0 commit comments

Comments
 (0)