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/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