|
|
@ -2,33 +2,13 @@ import { ABIDescription } from '@remixproject/plugin-api' |
|
|
|
import axios from 'axios' |
|
|
|
import axios from 'axios' |
|
|
|
import { remixClient } from './remix-client' |
|
|
|
import { remixClient } from './remix-client' |
|
|
|
import _ from 'lodash' |
|
|
|
import _ from 'lodash' |
|
|
|
|
|
|
|
import { VyperCompilationError , VyperCompilationOutput} from './types' |
|
|
|
|
|
|
|
|
|
|
|
export interface Contract { |
|
|
|
export interface Contract { |
|
|
|
name: string |
|
|
|
name: string |
|
|
|
content: string |
|
|
|
content: string |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export interface VyperCompilationResult { |
|
|
|
|
|
|
|
status: 'success' |
|
|
|
|
|
|
|
bytecode: string |
|
|
|
|
|
|
|
contractName?: string |
|
|
|
|
|
|
|
bytecode_runtime: string |
|
|
|
|
|
|
|
abi: ABIDescription[] |
|
|
|
|
|
|
|
ir: string |
|
|
|
|
|
|
|
method_identifiers: { |
|
|
|
|
|
|
|
[method: string]: string |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export interface VyperCompilationError { |
|
|
|
|
|
|
|
status: 'failed' |
|
|
|
|
|
|
|
column?: number |
|
|
|
|
|
|
|
line?: number |
|
|
|
|
|
|
|
message: string |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export type VyperCompilationOutput = VyperCompilationResult | VyperCompilationError |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Check if the output is an error */ |
|
|
|
/** Check if the output is an error */ |
|
|
|
export const isCompilationError = (output: VyperCompilationOutput): output is VyperCompilationError => output.status === 'failed' |
|
|
|
export const isCompilationError = (output: VyperCompilationOutput): output is VyperCompilationError => output.status === 'failed' |
|
|
|
|
|
|
|
|
|
|
@ -45,35 +25,6 @@ export function normalizeContractPath(contractPath: string): string[] { |
|
|
|
return [folders,resultingPath, filename] |
|
|
|
return [folders,resultingPath, filename] |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function parseErrorString(errorStructure: string[]) { |
|
|
|
|
|
|
|
// Split the string into lines
|
|
|
|
|
|
|
|
let errorType = '' |
|
|
|
|
|
|
|
let message = '' |
|
|
|
|
|
|
|
let tline = '' |
|
|
|
|
|
|
|
errorStructure.forEach(errorMsg => { |
|
|
|
|
|
|
|
const choppedup = errorMsg.split(': ') |
|
|
|
|
|
|
|
errorType = choppedup[0].trim().split('\n')[1] |
|
|
|
|
|
|
|
message = choppedup[1] |
|
|
|
|
|
|
|
// if (errorStructure.length > 2) {
|
|
|
|
|
|
|
|
// console.log(choppedup[2].split(',')[1])
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// console.log(choppedup)
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
let lines = errorStructure[0].trim().split('\n') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const errorObject = { |
|
|
|
|
|
|
|
status: 'failed', |
|
|
|
|
|
|
|
message: `${errorType} - ${message}`, |
|
|
|
|
|
|
|
column: '', |
|
|
|
|
|
|
|
line: '' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
message = null |
|
|
|
|
|
|
|
// targetLine = null
|
|
|
|
|
|
|
|
lines = null |
|
|
|
|
|
|
|
tline = null |
|
|
|
|
|
|
|
return errorObject |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const buildError = (output) => { |
|
|
|
const buildError = (output) => { |
|
|
|
if (isCompilationError(output)) { |
|
|
|
if (isCompilationError(output)) { |
|
|
|
const line = output.line |
|
|
|
const line = output.line |
|
|
@ -120,8 +71,9 @@ const compileReturnType = (output, contract) => { |
|
|
|
const depByteCode = evm.deployedBytecode |
|
|
|
const depByteCode = evm.deployedBytecode |
|
|
|
const runtimeBytecode = evm.bytecode |
|
|
|
const runtimeBytecode = evm.bytecode |
|
|
|
const methodIdentifiers = evm.methodIdentifiers |
|
|
|
const methodIdentifiers = evm.methodIdentifiers |
|
|
|
const version = output?.compilers[0]?.version ?? '0.4.0' |
|
|
|
// TODO: verify this is correct
|
|
|
|
const optimized = output?.compilers[0]?.settings?.optimize ?? true |
|
|
|
const version = output.version || '0.4.0' |
|
|
|
|
|
|
|
const optimized = output.optimize || true |
|
|
|
const evmVersion = '' |
|
|
|
const evmVersion = '' |
|
|
|
|
|
|
|
|
|
|
|
const result: { |
|
|
|
const result: { |
|
|
@ -179,7 +131,7 @@ const fixContractContent = (content: string) => { |
|
|
|
* @param url The url of the compiler |
|
|
|
* @param url The url of the compiler |
|
|
|
* @param contract The name and content of the contract |
|
|
|
* @param contract The name and content of the contract |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
export async function compile(url: string, contract: Contract): Promise<any> { |
|
|
|
export async function compile(url: string, contract: Contract): Promise<VyperCompilationOutput> { |
|
|
|
if (!contract.name) { |
|
|
|
if (!contract.name) { |
|
|
|
throw new Error('Set your Vyper contract file.') |
|
|
|
throw new Error('Set your Vyper contract file.') |
|
|
|
} |
|
|
|
} |
|
|
@ -211,7 +163,6 @@ export async function compile(url: string, contract: Contract): Promise<any> { |
|
|
|
contractName = null |
|
|
|
contractName = null |
|
|
|
response = null |
|
|
|
response = null |
|
|
|
let result: any |
|
|
|
let result: any |
|
|
|
let intermediateError |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const status = await (await axios.get(url + 'status/' + compileCode , { |
|
|
|
const status = await (await axios.get(url + 'status/' + compileCode , { |
|
|
|
method: 'Get' |
|
|
|
method: 'Get' |
|
|
@ -226,10 +177,7 @@ export async function compile(url: string, contract: Contract): Promise<any> { |
|
|
|
const intermediate = await(await axios.get(url + 'exceptions/' + compileCode , { |
|
|
|
const intermediate = await(await axios.get(url + 'exceptions/' + compileCode , { |
|
|
|
method: 'Get' |
|
|
|
method: 'Get' |
|
|
|
})).data |
|
|
|
})).data |
|
|
|
// console.log('Errors found', intermediate)
|
|
|
|
return intermediate |
|
|
|
result = parseErrorString(intermediate) |
|
|
|
|
|
|
|
intermediateError = intermediate |
|
|
|
|
|
|
|
return result |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
await new Promise((resolve) => setTimeout(() => resolve({}), 3000)) |
|
|
|
await new Promise((resolve) => setTimeout(() => resolve({}), 3000)) |
|
|
|
} |
|
|
|
} |
|
|
@ -293,12 +241,13 @@ export async function compileContract(contract: string, compilerUrl: string, set |
|
|
|
try { |
|
|
|
try { |
|
|
|
_contract = await remixClient.getContract() |
|
|
|
_contract = await remixClient.getContract() |
|
|
|
} catch (e: any) { |
|
|
|
} catch (e: any) { |
|
|
|
const errorGettingContract = { |
|
|
|
const errorGettingContract: VyperCompilationError = { |
|
|
|
status: 'failed', |
|
|
|
status: 'failed', |
|
|
|
message: e.message |
|
|
|
message: e.mesaage, |
|
|
|
|
|
|
|
error_type: 'fetch_contract' |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
remixClient.eventEmitter.emit('setOutput', errorGettingContract) |
|
|
|
remixClient.eventEmitter.emit('setOutput', { status: 'failed', errors: [errorGettingContract] } ) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
remixClient.changeStatus({ |
|
|
|
remixClient.changeStatus({ |
|
|
@ -306,10 +255,9 @@ export async function compileContract(contract: string, compilerUrl: string, set |
|
|
|
type: 'info', |
|
|
|
type: 'info', |
|
|
|
title: 'Compiling' |
|
|
|
title: 'Compiling' |
|
|
|
}) |
|
|
|
}) |
|
|
|
let output |
|
|
|
|
|
|
|
// try {
|
|
|
|
// try {
|
|
|
|
output = await compile(compilerUrl, _contract) |
|
|
|
let output = await compile(compilerUrl, _contract) |
|
|
|
if (output.status === 'failed') { |
|
|
|
if (output && output[0] && output[0].status === 'failed') { |
|
|
|
remixClient.changeStatus({ |
|
|
|
remixClient.changeStatus({ |
|
|
|
key: 'failed', |
|
|
|
key: 'failed', |
|
|
|
type: 'error', |
|
|
|
type: 'error', |
|
|
@ -317,13 +265,11 @@ export async function compileContract(contract: string, compilerUrl: string, set |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
setLoadingSpinnerState && setLoadingSpinnerState(false) |
|
|
|
setLoadingSpinnerState && setLoadingSpinnerState(false) |
|
|
|
remixClient.eventEmitter.emit('setOutput', { status: 'failed', message: output.message, title: 'Error compiling...', line: output.line, column: output.column, key: 1 }) |
|
|
|
remixClient.eventEmitter.emit('setOutput', { status: 'failed', errors: output }) |
|
|
|
output = null |
|
|
|
|
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SUCCESS
|
|
|
|
// SUCCESS
|
|
|
|
// remixClient.discardHighlight()
|
|
|
|
|
|
|
|
remixClient.changeStatus({ |
|
|
|
remixClient.changeStatus({ |
|
|
|
key: 'succeed', |
|
|
|
key: 'succeed', |
|
|
|
type: 'success', |
|
|
|
type: 'success', |
|
|
@ -336,9 +282,9 @@ export async function compileContract(contract: string, compilerUrl: string, set |
|
|
|
const contractName = _contract['name'] |
|
|
|
const contractName = _contract['name'] |
|
|
|
const compileResult = compileReturnType(output, contractName) |
|
|
|
const compileResult = compileReturnType(output, contractName) |
|
|
|
if (setOutput === null || setOutput === undefined) { |
|
|
|
if (setOutput === null || setOutput === undefined) { |
|
|
|
remixClient.eventEmitter.emit('setOutput', { contractName, compileResult }) |
|
|
|
remixClient.eventEmitter.emit('setOutput', { status: 'success', contractName, compileResult }) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
remixClient.eventEmitter.emit('setOutput', { contractName, compileResult }) |
|
|
|
remixClient.eventEmitter.emit('setOutput', { status: 'success', contractName, compileResult }) |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (err: any) { |
|
|
|
} catch (err: any) { |
|
|
|
remixClient.changeStatus({ |
|
|
|
remixClient.changeStatus({ |
|
|
@ -347,8 +293,14 @@ export async function compileContract(contract: string, compilerUrl: string, set |
|
|
|
title: `1 error occurred ${err.message}` |
|
|
|
title: `1 error occurred ${err.message}` |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const errorGettingContract: VyperCompilationError = { |
|
|
|
|
|
|
|
status: 'failed', |
|
|
|
|
|
|
|
message: err.mesaage, |
|
|
|
|
|
|
|
error_type: 'unknown_error' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
setLoadingSpinnerState && setLoadingSpinnerState(false) |
|
|
|
setLoadingSpinnerState && setLoadingSpinnerState(false) |
|
|
|
remixClient.eventEmitter.emit('setOutput', { status: 'failed', message: err.message }) |
|
|
|
remixClient.eventEmitter.emit('setOutput', { status: 'failed', errors: [errorGettingContract] }) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|