parent
03437f3295
commit
acb9e5892a
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"presets": ["@nrwl/react/babel"], |
||||||
|
"plugins": [] |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
# This file is used by: |
||||||
|
# 1. autoprefixer to adjust CSS to support the below specified browsers |
||||||
|
# 2. babel preset-env to adjust included polyfills |
||||||
|
# |
||||||
|
# For additional information regarding the format and rule options, please see: |
||||||
|
# https://github.com/browserslist/browserslist#queries |
||||||
|
# |
||||||
|
# If you need to support different browsers in production, you may tweak the list below. |
||||||
|
|
||||||
|
last 1 Chrome version |
||||||
|
last 1 Firefox version |
||||||
|
last 2 Edge major versions |
||||||
|
last 2 Safari major version |
||||||
|
last 2 iOS major versions |
||||||
|
Firefox ESR |
||||||
|
not IE 9-11 # For IE 9-11 support, remove 'not'. |
@ -0,0 +1,17 @@ |
|||||||
|
import React, { useState, useEffect } from 'react'; |
||||||
|
|
||||||
|
import { DebuggerUI } from '@remix-ui/debugger-ui' // eslint-disable-line
|
||||||
|
|
||||||
|
import { DebuggerClientApi } from './debugger' |
||||||
|
|
||||||
|
const remix = new DebuggerClientApi() |
||||||
|
|
||||||
|
export const App = () => {
|
||||||
|
return ( |
||||||
|
<div className="debugger"> |
||||||
|
<DebuggerUI debuggerAPI={remix} /> |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default App; |
@ -0,0 +1,157 @@ |
|||||||
|
import Web3 from 'web3' |
||||||
|
import remixDebug, { TransactionDebugger as Debugger } from '@remix-project/remix-debug' |
||||||
|
import { CompilationOutput, Sources } from '@remix-ui/debugger-ui' |
||||||
|
import type { CompilationResult } from '@remix-project/remix-solidity-ts' |
||||||
|
|
||||||
|
export const DebuggerApiMixin = (Base) => class extends Base { |
||||||
|
initDebuggerApi () { |
||||||
|
this.debugHash = null |
||||||
|
|
||||||
|
const self = this |
||||||
|
this.web3Provider = { |
||||||
|
sendAsync(payload, callback) { |
||||||
|
self.call('web3Provider', 'sendAsync', payload) |
||||||
|
.then(result => callback(null, result)) |
||||||
|
.catch(e => callback(e)) |
||||||
|
} |
||||||
|
} |
||||||
|
this._web3 = new Web3(this.web3Provider) |
||||||
|
|
||||||
|
this.offsetToLineColumnConverter = { |
||||||
|
async offsetToLineColumn (rawLocation, file, sources, asts) { |
||||||
|
return await self.call('offsetToLineColumnConverter', 'offsetToLineColumn', rawLocation, file, sources, asts) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// on()
|
||||||
|
// call()
|
||||||
|
// onDebugRequested()
|
||||||
|
// onRemoveHighlights()
|
||||||
|
|
||||||
|
web3 () { |
||||||
|
return this._web3 |
||||||
|
} |
||||||
|
|
||||||
|
async discardHighlight () { |
||||||
|
await this.call('editor', 'discardHighlight') |
||||||
|
} |
||||||
|
|
||||||
|
async highlight (lineColumnPos, path) { |
||||||
|
await this.call('editor', 'highlight', lineColumnPos, path) |
||||||
|
} |
||||||
|
|
||||||
|
async getFile (path) { |
||||||
|
return await this.call('fileManager', 'getFile', path) |
||||||
|
} |
||||||
|
|
||||||
|
async setFile (path, content) { |
||||||
|
await this.call('fileManager', 'setFile', path, content) |
||||||
|
} |
||||||
|
|
||||||
|
onBreakpointCleared (listener) { |
||||||
|
this.onBreakpointClearedListener = listener |
||||||
|
} |
||||||
|
|
||||||
|
onBreakpointAdded (listener) { |
||||||
|
this.onBreakpointAddedListener = listener |
||||||
|
} |
||||||
|
|
||||||
|
onEditorContentChanged (listener) { |
||||||
|
this.onEditorContentChangedListener = listener |
||||||
|
} |
||||||
|
|
||||||
|
onDebugRequested (listener) { |
||||||
|
this.onDebugRequestedListener = listener |
||||||
|
} |
||||||
|
|
||||||
|
onRemoveHighlights (listener) { |
||||||
|
this.onRemoveHighlightsListener = listener |
||||||
|
} |
||||||
|
|
||||||
|
async fetchContractAndCompile (address, receipt) { |
||||||
|
const target = (address && remixDebug.traceHelper.isContractCreation(address)) ? receipt.contractAddress : address |
||||||
|
const targetAddress = target || receipt.contractAddress || receipt.to |
||||||
|
const codeAtAddress = await this._web3.eth.getCode(targetAddress) |
||||||
|
const output = await this.call('fetchAndCompile', 'resolve', targetAddress, codeAtAddress, 'browser/.debug') |
||||||
|
return new CompilerAbstract(output.languageversion, output.data, output.source) |
||||||
|
} |
||||||
|
|
||||||
|
async getDebugWeb3 () { |
||||||
|
let web3 |
||||||
|
let network |
||||||
|
try { |
||||||
|
network = await this.call('network', 'detectNetwork')
|
||||||
|
} catch (e) { |
||||||
|
web3 = this.web3() |
||||||
|
} |
||||||
|
if (!web3) { |
||||||
|
const webDebugNode = remixDebug.init.web3DebugNode(network.name) |
||||||
|
web3 = !webDebugNode ? this.web3() : webDebugNode |
||||||
|
} |
||||||
|
remixDebug.init.extendWeb3(web3) |
||||||
|
return web3 |
||||||
|
} |
||||||
|
|
||||||
|
async getTrace (hash) { |
||||||
|
if (!hash) return |
||||||
|
const web3 = await this.getDebugWeb3() |
||||||
|
const currentReceipt = await web3.eth.getTransactionReceipt(hash) |
||||||
|
const debug = new Debugger({ |
||||||
|
web3, |
||||||
|
offsetToLineColumnConverter: this.offsetToLineColumnConverter, |
||||||
|
compilationResult: async (address) => { |
||||||
|
try { |
||||||
|
return await this.fetchContractAndCompile(address, currentReceipt) |
||||||
|
} catch (e) { |
||||||
|
console.error(e) |
||||||
|
} |
||||||
|
return null |
||||||
|
}, |
||||||
|
debugWithGeneratedSources: false |
||||||
|
}) |
||||||
|
return await debug.debugger.traceManager.getTrace(hash) |
||||||
|
} |
||||||
|
|
||||||
|
debug (hash) { |
||||||
|
this.debugHash = hash |
||||||
|
this.onDebugRequestedListener(hash) |
||||||
|
} |
||||||
|
|
||||||
|
onActivation () { |
||||||
|
this.on('editor', 'breakpointCleared', (fileName, row) => this.onBreakpointClearedListener(fileName, row)) |
||||||
|
this.on('editor', 'breakpointAdded', (fileName, row) => this.onBreakpointAddedListener(fileName, row)) |
||||||
|
this.on('editor', 'contentChanged', () => this.onEditorContentChangedListener())
|
||||||
|
} |
||||||
|
|
||||||
|
onDeactivation () { |
||||||
|
this.onRemoveHighlightsListener() |
||||||
|
this.off('editor', 'breakpointCleared') |
||||||
|
this.off('editor', 'breakpointAdded') |
||||||
|
this.off('editor', 'contentChanged') |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export class CompilerAbstract implements CompilationOutput { // this is a subset of /remix-ide/src/app/compiler/compiler-abstract.js
|
||||||
|
languageversion |
||||||
|
data |
||||||
|
source |
||||||
|
|
||||||
|
constructor (languageversion: string, data: CompilationResult, source: { sources: Sources, target: string }) { |
||||||
|
this.languageversion = languageversion |
||||||
|
this.data = data |
||||||
|
this.source = source // source code
|
||||||
|
} |
||||||
|
|
||||||
|
getSourceName (fileIndex) { |
||||||
|
if (this.data && this.data.sources) { |
||||||
|
return Object.keys(this.data.sources)[fileIndex] |
||||||
|
} else if (Object.keys(this.source.sources).length === 1) { |
||||||
|
// if we don't have ast, we return the only one filename present.
|
||||||
|
const sourcesArray = Object.keys(this.source.sources) |
||||||
|
return sourcesArray[0] |
||||||
|
} |
||||||
|
return null |
||||||
|
}
|
||||||
|
} |
||||||
|
|
@ -0,0 +1,28 @@ |
|||||||
|
import { PluginClient } from "@remixproject/plugin"; |
||||||
|
import { createClient } from "@remixproject/plugin-webview"; |
||||||
|
import { IDebuggerApi, RawLocation, Sources, Asts, LineColumnLocation,
|
||||||
|
onBreakpointClearedListener, onBreakpointAddedListener, onEditorContentChanged, TransactionReceipt } from '@remix-ui/debugger-ui' |
||||||
|
import { DebuggerApiMixin, CompilerAbstract} from './debugger-api' |
||||||
|
|
||||||
|
export class DebuggerClientApi extends DebuggerApiMixin(PluginClient) {
|
||||||
|
constructor () { |
||||||
|
super()
|
||||||
|
createClient(this as any) |
||||||
|
this.initDebuggerApi() |
||||||
|
} |
||||||
|
|
||||||
|
offsetToLineColumnConverter: IDebuggerApi['offsetToLineColumnConverter'] |
||||||
|
debugHash: string |
||||||
|
debugHashRequest: number |
||||||
|
removeHighlights: boolean |
||||||
|
onBreakpointCleared: (listener: onBreakpointClearedListener) => void |
||||||
|
onBreakpointAdded: (listener: onBreakpointAddedListener) => void |
||||||
|
onEditorContentChanged: (listener: onEditorContentChanged) => void |
||||||
|
discardHighlight: () => Promise<void> |
||||||
|
highlight: (lineColumnPos: LineColumnLocation, path: string) => Promise<void> |
||||||
|
fetchContractAndCompile: (address: string, currentReceipt: TransactionReceipt) => Promise<CompilerAbstract> |
||||||
|
getFile: (path: string) => Promise<string> |
||||||
|
setFile: (path: string, content: string) => Promise<void> |
||||||
|
getDebugWeb3: () => any // returns an instance of web3.js
|
||||||
|
} |
||||||
|
|
@ -0,0 +1,3 @@ |
|||||||
|
export const environment = { |
||||||
|
production: true |
||||||
|
}; |
@ -0,0 +1,6 @@ |
|||||||
|
// This file can be replaced during build by using the `fileReplacements` array.
|
||||||
|
// When building for production, this file is replaced with `environment.prod.ts`.
|
||||||
|
|
||||||
|
export const environment = { |
||||||
|
production: false |
||||||
|
}; |
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,15 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8" /> |
||||||
|
<title>Debugger</title> |
||||||
|
<base href="/" /> |
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico" /> |
||||||
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous"/> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div id="root"></div> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1 @@ |
|||||||
|
export * from './app/debugger-api'; |
@ -0,0 +1,9 @@ |
|||||||
|
import React from 'react'; |
||||||
|
import ReactDOM from 'react-dom'; |
||||||
|
|
||||||
|
import App from './app/app'; |
||||||
|
|
||||||
|
ReactDOM.render( |
||||||
|
<App />, |
||||||
|
document.getElementById('root') |
||||||
|
); |
@ -0,0 +1,7 @@ |
|||||||
|
/** |
||||||
|
* Polyfill stable language features. These imports will be optimized by `@babel/preset-env`. |
||||||
|
* |
||||||
|
* See: https://github.com/zloirock/core-js#babel
|
||||||
|
*/ |
||||||
|
import 'core-js/stable'; |
||||||
|
import 'regenerator-runtime/runtime'; |
@ -0,0 +1 @@ |
|||||||
|
/* You can add global styles to this file, and also import other style files */ |
@ -0,0 +1,9 @@ |
|||||||
|
{ |
||||||
|
"extends": "./tsconfig.json", |
||||||
|
"compilerOptions": { |
||||||
|
"outDir": "../../dist/out-tsc", |
||||||
|
"types": ["node"] |
||||||
|
}, |
||||||
|
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"], |
||||||
|
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
{ |
||||||
|
"extends": "../../tsconfig.json", |
||||||
|
"compilerOptions": { |
||||||
|
"jsx": "react", |
||||||
|
"allowJs": true, |
||||||
|
"esModuleInterop": true, |
||||||
|
"allowSyntheticDefaultImports": true, |
||||||
|
"types": ["node", "jest"], |
||||||
|
"resolveJsonModule": true |
||||||
|
}, |
||||||
|
"files": [ |
||||||
|
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts", |
||||||
|
"../../node_modules/@nrwl/react/typings/image.d.ts" |
||||||
|
], |
||||||
|
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
{ |
||||||
|
"extends": "./tsconfig.json", |
||||||
|
"compilerOptions": { |
||||||
|
"outDir": "../../dist/out-tsc", |
||||||
|
"module": "commonjs", |
||||||
|
"types": ["jest", "node"] |
||||||
|
}, |
||||||
|
"include": [ |
||||||
|
"**/*.spec.ts", |
||||||
|
"**/*.spec.tsx", |
||||||
|
"**/*.spec.js", |
||||||
|
"**/*.spec.jsx", |
||||||
|
"**/*.d.ts" |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
const nxWebpack = require('@nrwl/react/plugins/webpack') |
||||||
|
|
||||||
|
module.exports = config => { |
||||||
|
const nxWebpackConfig = nxWebpack(config) |
||||||
|
|
||||||
|
return { |
||||||
|
...nxWebpackConfig, |
||||||
|
node: { |
||||||
|
fs: 'empty', |
||||||
|
tls: 'empty', |
||||||
|
readline: 'empty', |
||||||
|
net: 'empty', |
||||||
|
module: 'empty', |
||||||
|
child_process: 'empty' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1 +1,3 @@ |
|||||||
export * from './lib/debugger-ui' |
export * from './lib/debugger-ui' |
||||||
|
export * from './lib/idebugger-api' |
||||||
|
export * from './lib/idebugger-api' |
||||||
|
@ -1,64 +0,0 @@ |
|||||||
|
|
||||||
import type { CompilationResult, CompilationSource } from '@remix-project/remix-solidity-ts' |
|
||||||
|
|
||||||
export interface DebuggerUIProps { |
|
||||||
debuggerAPI: DebuggerAPI
|
|
||||||
} |
|
||||||
|
|
||||||
interface EditorEvent { |
|
||||||
event: {
|
|
||||||
register(eventName: 'breakpointCleared' | 'breakpointAdded' | 'contentChanged',
|
|
||||||
callback: (fileName: string, row: string | number) => void)
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
interface LineColumnLocation { |
|
||||||
start: { |
|
||||||
line: number, column: number |
|
||||||
},
|
|
||||||
end: { |
|
||||||
line: number, column: number |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
interface RawLocation { |
|
||||||
start: number, length: number |
|
||||||
} |
|
||||||
|
|
||||||
interface Sources { |
|
||||||
[fileName: string] : {content: string} |
|
||||||
} |
|
||||||
|
|
||||||
interface CompilationOutput { |
|
||||||
source: { sources: Sources, target: string } |
|
||||||
data: CompilationResult |
|
||||||
getSourceName: (id: number) => string |
|
||||||
} |
|
||||||
|
|
||||||
interface Asts { |
|
||||||
[fileName: string] : CompilationSource // ast
|
|
||||||
} |
|
||||||
|
|
||||||
interface TransactionReceipt { |
|
||||||
blockHash: string |
|
||||||
blockNumber: number |
|
||||||
transactionHash: string |
|
||||||
transactionIndex: number |
|
||||||
from: string |
|
||||||
to: string |
|
||||||
contractAddress: string | null
|
|
||||||
} |
|
||||||
|
|
||||||
export interface DebuggerAPI { |
|
||||||
offsetToLineColumnConverter: { offsetToLineColumn: (sourceLocation: RawLocation, file: number, contents: Sources, asts: Asts) => LineColumnLocation } |
|
||||||
debugHash: string |
|
||||||
debugHashRequest: string |
|
||||||
removeHighlights: boolean |
|
||||||
editor: EditorEvent |
|
||||||
discardHighlight: () => void |
|
||||||
highlight: (lineColumnPos: LineColumnLocation, path: string) => void |
|
||||||
fetchContractAndCompile: (address: string, currentReceipt: TransactionReceipt) => CompilationOutput |
|
||||||
getFile: (path: string) => string |
|
||||||
setFile: (path: string, content: string) => void |
|
||||||
getDebugWeb3: () => any // returns an instance of web3.js
|
|
||||||
}
|
|
@ -0,0 +1,66 @@ |
|||||||
|
|
||||||
|
import type { CompilationResult, CompilationSource } from '@remix-project/remix-solidity-ts' |
||||||
|
|
||||||
|
export interface DebuggerUIProps { |
||||||
|
debuggerAPI: IDebuggerApi
|
||||||
|
} |
||||||
|
|
||||||
|
export interface LineColumnLocation { |
||||||
|
start: { |
||||||
|
line: number, column: number |
||||||
|
},
|
||||||
|
end: { |
||||||
|
line: number, column: number |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export interface RawLocation { |
||||||
|
start: number, length: number |
||||||
|
} |
||||||
|
|
||||||
|
export interface Sources { |
||||||
|
[fileName: string] : {content: string} |
||||||
|
} |
||||||
|
|
||||||
|
export interface CompilationOutput { |
||||||
|
source: { sources: Sources, target: string } |
||||||
|
data: CompilationResult |
||||||
|
getSourceName: (id: number) => string |
||||||
|
} |
||||||
|
|
||||||
|
export interface Asts { |
||||||
|
[fileName: string] : CompilationSource // ast
|
||||||
|
} |
||||||
|
|
||||||
|
export interface TransactionReceipt { |
||||||
|
blockHash: string |
||||||
|
blockNumber: number |
||||||
|
transactionHash: string |
||||||
|
transactionIndex: number |
||||||
|
from: string |
||||||
|
to: string |
||||||
|
contractAddress: string | null
|
||||||
|
} |
||||||
|
|
||||||
|
export type onBreakpointClearedListener = (params: string, row: number) => void |
||||||
|
export type onBreakpointAddedListener = (params: string, row: number) => void |
||||||
|
export type onEditorContentChanged = () => void |
||||||
|
export type onDebugRequested = (hash: string) => void |
||||||
|
|
||||||
|
export interface IDebuggerApi { |
||||||
|
offsetToLineColumnConverter: { offsetToLineColumn: (sourceLocation: RawLocation, file: number, contents: Sources, asts: Asts) => Promise<LineColumnLocation> } |
||||||
|
debugHash: string |
||||||
|
debugHashRequest: number |
||||||
|
removeHighlights: boolean |
||||||
|
onRemoveHighlights: (listener: VoidFunction) => void |
||||||
|
onDebugRequested: (listener: onDebugRequested) => void |
||||||
|
onBreakpointCleared: (listener: onBreakpointClearedListener) => void |
||||||
|
onBreakpointAdded: (listener: onBreakpointAddedListener) => void |
||||||
|
onEditorContentChanged: (listener: onEditorContentChanged) => void |
||||||
|
discardHighlight: () => Promise<void> |
||||||
|
highlight: (lineColumnPos: LineColumnLocation, path: string) => Promise<void> |
||||||
|
fetchContractAndCompile: (address: string, currentReceipt: TransactionReceipt) => Promise<CompilationOutput> |
||||||
|
getFile: (path: string) => Promise<string> |
||||||
|
setFile: (path: string, content: string) => Promise<void> |
||||||
|
getDebugWeb3: () => any // returns an instance of web3.js
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,65 @@ |
|||||||
|
{ |
||||||
|
"rulesDirectory": ["node_modules/@nrwl/workspace/src/tslint"], |
||||||
|
"linterOptions": { |
||||||
|
"exclude": ["**/*"] |
||||||
|
}, |
||||||
|
"rules": { |
||||||
|
"arrow-return-shorthand": true, |
||||||
|
"callable-types": true, |
||||||
|
"class-name": true, |
||||||
|
"deprecation": { |
||||||
|
"severity": "warn" |
||||||
|
}, |
||||||
|
"forin": true, |
||||||
|
"import-blacklist": [true, "rxjs/Rx"], |
||||||
|
"interface-over-type-literal": true, |
||||||
|
"member-access": false, |
||||||
|
"member-ordering": [ |
||||||
|
true, |
||||||
|
{ |
||||||
|
"order": [ |
||||||
|
"static-field", |
||||||
|
"instance-field", |
||||||
|
"static-method", |
||||||
|
"instance-method" |
||||||
|
] |
||||||
|
} |
||||||
|
], |
||||||
|
"no-arg": true, |
||||||
|
"no-bitwise": true, |
||||||
|
"no-console": [true, "debug", "info", "time", "timeEnd", "trace"], |
||||||
|
"no-construct": true, |
||||||
|
"no-debugger": true, |
||||||
|
"no-duplicate-super": true, |
||||||
|
"no-empty": false, |
||||||
|
"no-empty-interface": true, |
||||||
|
"no-eval": true, |
||||||
|
"no-inferrable-types": [true, "ignore-params"], |
||||||
|
"no-misused-new": true, |
||||||
|
"no-non-null-assertion": true, |
||||||
|
"no-shadowed-variable": true, |
||||||
|
"no-string-literal": false, |
||||||
|
"no-string-throw": true, |
||||||
|
"no-switch-case-fall-through": true, |
||||||
|
"no-unnecessary-initializer": true, |
||||||
|
"no-unused-expression": true, |
||||||
|
"no-var-keyword": true, |
||||||
|
"object-literal-sort-keys": false, |
||||||
|
"prefer-const": true, |
||||||
|
"radix": true, |
||||||
|
"triple-equals": [true, "allow-null-check"], |
||||||
|
"unified-signatures": true, |
||||||
|
"variable-name": false, |
||||||
|
|
||||||
|
"nx-enforce-module-boundaries": [ |
||||||
|
true, |
||||||
|
{ |
||||||
|
"enforceBuildableLibDependency": true, |
||||||
|
"allow": [], |
||||||
|
"depConstraints": [ |
||||||
|
{ "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] } |
||||||
|
] |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue